简体   繁体   English

从BufferedImage转换为SWT图像

[英]Conversion from BufferedImage to SWT Image

After much looking, I found a bit of code that converts a BufferedImage to a SWT Image (don't bother reading it yet): 经过深思熟虑后,我发现了一些将BufferedImage转换为SWT图像的代码(不用费心去读取它):

public static ImageData convertToSWT(BufferedImage bufferedImage) {
    if (bufferedImage.getColorModel() instanceof DirectColorModel) {
        DirectColorModel colorModel = (DirectColorModel) bufferedImage.getColorModel();
        PaletteData palette = new PaletteData(
            colorModel.getRedMask(),
            colorModel.getGreenMask(),
            colorModel.getBlueMask()
        );
        ImageData data = new ImageData(
            bufferedImage.getWidth(),
            bufferedImage.getHeight(), colorModel.getPixelSize(),
            palette
        );
        WritableRaster raster = bufferedImage.getRaster();
        int[] pixelArray = new int[3];
        for (int y = 0; y < data.height; y++) {
            for (int x = 0; x < data.width; x++) {
                raster.getPixel(x, y, pixelArray);
                int pixel = palette.getPixel(
                    new RGB(pixelArray[0], pixelArray[1], pixelArray[2])
                );
                data.setPixel(x, y, pixel);
            }
        }
        return data;
    } else if (bufferedImage.getColorModel() instanceof IndexColorModel) {
        IndexColorModel colorModel = (IndexColorModel) bufferedImage.getColorModel();
        int size = colorModel.getMapSize();
        byte[] reds = new byte[size];
        byte[] greens = new byte[size];
        byte[] blues = new byte[size];
        colorModel.getReds(reds);
        colorModel.getGreens(greens);
        colorModel.getBlues(blues);
        RGB[] rgbs = new RGB[size];
        for (int i = 0; i < rgbs.length; i++) {
            rgbs[i] = new RGB(reds[i] & 0xFF, greens[i] & 0xFF, blues[i] & 0xFF);
        }
        PaletteData palette = new PaletteData(rgbs);
        ImageData data = new ImageData(
            bufferedImage.getWidth(),
            bufferedImage.getHeight(),
            colorModel.getPixelSize(),
            palette
        );
        data.transparentPixel = colorModel.getTransparentPixel();
        WritableRaster raster = bufferedImage.getRaster();
        int[] pixelArray = new int[1];
        for (int y = 0; y < data.height; y++) {
            for (int x = 0; x < data.width; x++) {
                raster.getPixel(x, y, pixelArray);
                data.setPixel(x, y, pixelArray[0]);
            }
        }
        return data;
    }
    return null;
}

(found here: http://www.java2s.com/Code/Java/SWT-JFace-Eclipse/ConvertsabufferedimagetoSWTImageData.htm ). (在此处找到: http//www.java2s.com/Code/Java/SWT-JFace-Eclipse/ConvertsabufferedimagetoSWTImageData.htm )。

I've tested it, and it works just fine. 我测试过它,它运行得很好。 The problem is that I don't understand it (my best guess is that it uses the raw data interfaces of both to make the transfer). 问题是我不理解它(我最好的猜测是它使用两者的原始数据接口来进行传输)。 It occurred to me that a much simpler solution would be to write the BufferedImage out to ByteArrayOutputStream , and then read it back into a SWT Image with ByteArrayInputStream . 在我看来,更简单的解决方案是将BufferedImage写入ByteArrayOutputStream ,然后使用ByteArrayInputStream将其读回SWT图像。 Are there any problems with this solution? 这个解决方案有什么问题吗? What about speed? 速度怎么样?

This conversion is necessary because all of the image resizing libraries out there are for AWT, and yet I'm displaying the image with SWT. 这种转换是必要的,因为所有的图像大小调整库都用于AWT,但我用SWT显示图像。

Thanks! 谢谢!

This is a more complete version... The one posted in the question does not work for me. 这是一个更完整的版本...问题中发布的版本对我不起作用。

/**
 * snippet 156: convert between SWT Image and AWT BufferedImage.
 * <p>
 * For a list of all SWT example snippets see
 * http://www.eclipse.org/swt/snippets/
 */
public static ImageData convertToSWT(BufferedImage bufferedImage) {
    if (bufferedImage.getColorModel() instanceof DirectColorModel) {
        /*
        DirectColorModel colorModel = (DirectColorModel)bufferedImage.getColorModel();
        PaletteData palette = new PaletteData(
                colorModel.getRedMask(),
                colorModel.getGreenMask(),
                colorModel.getBlueMask());
        ImageData data = new ImageData(bufferedImage.getWidth(), bufferedImage.getHeight(),
                colorModel.getPixelSize(), palette);
        WritableRaster raster = bufferedImage.getRaster();
        int[] pixelArray = new int[3];
        for (int y = 0; y < data.height; y++) {
            for (int x = 0; x < data.width; x++) {
                raster.getPixel(x, y, pixelArray);
                int pixel = palette.getPixel(new RGB(pixelArray[0], pixelArray[1], pixelArray[2]));
                data.setPixel(x, y, pixel);
            }
        }
        */
        DirectColorModel colorModel = (DirectColorModel)bufferedImage.getColorModel();
        PaletteData palette = new PaletteData(
                colorModel.getRedMask(),
                colorModel.getGreenMask(),
                colorModel.getBlueMask());
        ImageData data = new ImageData(bufferedImage.getWidth(), bufferedImage.getHeight(),
                colorModel.getPixelSize(), palette);
        for (int y = 0; y < data.height; y++) {
            for (int x = 0; x < data.width; x++) {
                int rgb = bufferedImage.getRGB(x, y);
                int pixel = palette.getPixel(new RGB((rgb >> 16) & 0xFF, (rgb >> 8) & 0xFF, rgb & 0xFF));
                data.setPixel(x, y, pixel);
                if (colorModel.hasAlpha()) {
                    data.setAlpha(x, y, (rgb >> 24) & 0xFF);
                }
            }
        }
        return data;
    }
    else if (bufferedImage.getColorModel() instanceof IndexColorModel) {
        IndexColorModel colorModel = (IndexColorModel)bufferedImage.getColorModel();
        int size = colorModel.getMapSize();
        byte[] reds = new byte[size];
        byte[] greens = new byte[size];
        byte[] blues = new byte[size];
        colorModel.getReds(reds);
        colorModel.getGreens(greens);
        colorModel.getBlues(blues);
        RGB[] rgbs = new RGB[size];
        for (int i = 0; i < rgbs.length; i++) {
            rgbs[i] = new RGB(reds[i] & 0xFF, greens[i] & 0xFF, blues[i] & 0xFF);
        }
        PaletteData palette = new PaletteData(rgbs);
        ImageData data = new ImageData(bufferedImage.getWidth(), bufferedImage.getHeight(),
                colorModel.getPixelSize(), palette);
        data.transparentPixel = colorModel.getTransparentPixel();
        WritableRaster raster = bufferedImage.getRaster();
        int[] pixelArray = new int[1];
        for (int y = 0; y < data.height; y++) {
            for (int x = 0; x < data.width; x++) {
                raster.getPixel(x, y, pixelArray);
                data.setPixel(x, y, pixelArray[0]);
            }
        }
        return data;
    }
    else if (bufferedImage.getColorModel() instanceof ComponentColorModel) {
        ComponentColorModel colorModel = (ComponentColorModel)bufferedImage.getColorModel();
        //ASSUMES: 3 BYTE BGR IMAGE TYPE
        PaletteData palette = new PaletteData(0x0000FF, 0x00FF00,0xFF0000);
        ImageData data = new ImageData(bufferedImage.getWidth(), bufferedImage.getHeight(),
                colorModel.getPixelSize(), palette);
        //This is valid because we are using a 3-byte Data model with no transparent pixels
        data.transparentPixel = -1;
        WritableRaster raster = bufferedImage.getRaster();
        int[] pixelArray = new int[3];
        for (int y = 0; y < data.height; y++) {
            for (int x = 0; x < data.width; x++) {
                raster.getPixel(x, y, pixelArray);
                int pixel = palette.getPixel(new RGB(pixelArray[0], pixelArray[1], pixelArray[2]));
                data.setPixel(x, y, pixel);
            }
        }
        return data;
    }
    return null;
}

The complexity of the code is mainly due to the two possible color models of BufferedImage . 代码的复杂性主要是由于BufferedImage的两种可能的颜色模型。 I don't think you can improve much on this. 我不认为你可以在这方面有所改进。 First of all, the use of an intermediate Stream will require the two image systems have a common format, and the conversion to/from a Stream is definitely going to be way slower that the current code. 首先,使用中间Stream将要求两个图像系统具有通用格式,并且与Stream的转换Stream当前代码慢。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM