Преобразование кода java .awt. * В код Android .graphics. * - PullRequest
1 голос
/ 13 апреля 2020

Я пытаюсь перенести некоторый графический код, написанный с использованием библиотеки java.awt.*, чтобы использовать библиотеку android.graphics.*. Однако у меня нет большого опыта работы с графикой.

Вот код java.awt.* (который работает):

    /**
     * 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);
        }
    }

Это класс MyImageBitmap:

/**
 * 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
}

Вот что я попробовал (но безуспешно):

    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);
        }
    }

Когда я запускаю приведенный выше код (моя попытка портирования через код awt), я получаю ArrayIndexOutOfBoundsException в этой строке r = (int)(0xFF & imgRGB888[3*ci]);.

1 Ответ

0 голосов
/ 24 апреля 2020

Я понял, в чем проблема. Мой алгоритм для преобразования из байтового массива в массив цвета int был неправильным. Ниже приведена правильная реализация. Изображения теперь правильно отображаются в 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);
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...