Converting java.awt.* code to Android.graphics.* code

1

I am trying to port some graphics code that is written using java.awt.* library to instead use the android.graphics.* library. However, I don't have much experience with graphics.

Here is the java.awt.* code (which works):

    /**
     * Converts the given <code>MyImageBitmap</code> to the specified image format and returns it as byte array.
     *
     * @param myImageBitmapthe given MyImageBitmap, not null
     * @param format the given target image format ("png", "gif", "jpg"), not null
     * @return the converted data in byte array format, not null
     */
    private byte[] convert(MyImageBitmap myImageBitmap, String format) {
        final int width = myImageBitmap.getWidth();
        final int height = myImageBitmap.getHeight();

        final int[] MASKS = {0x000000ff, 0x000000ff, 0x000000ff};

        DataBuffer buffer = new DataBufferByte(myImageBitmap.getPixels(), myImageBitmap.getLength());
        WritableRaster writableRaster = Raster.createPackedRaster(buffer, width, height, width, MASKS, null);
        BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        bufferedImage.setData(writableRaster);

        try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
            ImageIO.write(bufferedImage, format, outputStream);
            outputStream.close();
            return outputStream.toByteArray();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

This is the MyImageBitmap class:

/**
 * A <code>MyImageBitmap</code> instance contains an image information in bitmap format.
 */
public class MyImageBitmap implements Serializable {

    //...member variables

    /**
     * Creates an instance of <code>MyImageBitmap</code> with specified data.
     *
     * @param pixels    the image pixes, not null
     * @param width     the image width, not null
     * @param height    the image height, not null
     * @param ppi       pixel per inch, not null
     * @param depth     the image depth, not null
     * @param lossyFlag lossy flag, not null
     */
    public MyImageBitmap(byte[] pixels, int width, int height, int ppi, int depth, int lossyFlag) {
        this.pixels = pixels;
        this.width = width;
        this.height = height;
        this.ppi = ppi;
        this.depth = depth;
        this.lossyFlag = lossyFlag;

        this.length = pixels != null ? pixels.length : 0;
    }

    //...getters
}

This is what I have tried (with no success):

    private byte[] convert(MyImageBitmap myImageBitmap, String format) {
        int width = myImageBitmap.getWidth();
        int height = myImageBitmap.getHeight();

        byte[] imgRGB888 = myImageBitmap.getPixels();

        Bitmap bmp2 = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);

        int[] colors = new int[width * height];
        int r,g,b;
        for (int ci = 0; ci < colors.length; ci++)
        {
            r = (int)(0xFF & imgRGB888[3*ci]);
            g = (int)(0xFF & imgRGB888[3*ci+1]);
            b = (int)(0xFF & imgRGB888[3*ci+2]);
            colors[ci] = Color.rgb(r, g, b);
        }

        bmp2.setPixels(colors, 0, width, 0, 0, width, height);

        Bitmap.CompressFormat compressFormat;

        if (format.equals("jpeg")){
            compressFormat = android.graphics.Bitmap.CompressFormat.JPEG;
        }else if (format.equals("png")){
            compressFormat = android.graphics.Bitmap.CompressFormat.PNG;
        }else {//must be gif...try to convert to png
            compressFormat = android.graphics.Bitmap.CompressFormat.PNG;
        }

        try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()){
            bmp2.compress(compressFormat, 100, outputStream);
            return outputStream.toByteArray();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

When I run the above code (my attempt at porting over the awt code) I get an ArrayIndexOutOfBoundsException on this line r = (int)(0xFF & imgRGB888[3*ci]);.

java
android
bitmap
awt
android-bitmap
asked on Stack Overflow Apr 13, 2020 by alexander antaya • edited Apr 15, 2020 by halfer

1 Answer

0

I ended up figuring out what the issue was. My algorithm for converting from byte array to int color array was wrong. Below is the correct implementation. The images are now being correctly displayed in the Android ImageView!

    /**
     * Converts the given <code>MyImageBitmap</code> to the specified image format and returns it as byte array.
     *
     * @param myImageBitmap the given bitmap, not null
     * @param format the given target image format, not null
     * @return the converted data in byte array format, not null
     */
    private byte[] convert(MyImageBitmap myImageBitmap, String format) {
        int width = myImageBitmap.getWidth();
        int height = myImageBitmap.getHeight();

        byte[] imgRGB888 = myImageBitmap.getPixels();

        Bitmap bmp2 = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);

        int[] colors = new int[width * height];

        //We need to convert the image from a byte array to a
        // int color array so we can create the Android Bitmap
        int r,g,b;
        for (int ci = 0; ci < colors.length; ci++) {
            r = (int)(0x000000ff & imgRGB888[ci]);
            g = (int)(0x000000ff & imgRGB888[ci]);
            b = (int)(0x000000ff & imgRGB888[ci]);
            colors[ci] = Color.rgb(r, g, b);
        }

        bmp2.setPixels(colors, 0, width, 0, 0, width, height);

        Bitmap.CompressFormat compressFormat;

        if (format.equals("jpeg")){
            compressFormat = android.graphics.Bitmap.CompressFormat.JPEG;
        }else{//must be png
            compressFormat = android.graphics.Bitmap.CompressFormat.PNG;
        }

        try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()){
            bmp2.compress(compressFormat, 100, outputStream);
            return outputStream.toByteArray();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
answered on Stack Overflow Apr 24, 2020 by alexander antaya

User contributions licensed under CC BY-SA 3.0