Более быстрая альтернатива ColorConvertOp

У меня есть метод преобразования BufferedImages типа TYPE_CUSTOM в TYPE_INT_RGB. Я использую следующий код, однако мне бы очень хотелось найти более быстрый способ сделать это.

BufferedImage newImg = new BufferedImage(
    src.getWidth(), 
    src.getHeight(), 
    BufferedImage.TYPE_INT_RGB);

ColorConvertOp op = new ColorConvertOp(null);
op.filter(src, newImg);

Он работает нормально, но довольно медленно, и мне интересно, есть ли более быстрый способ сделать это преобразование.

ColorModel до преобразования:

ColorModel: #pixelBits = 24 numComponents = 3 color space = java.awt.color.ICC_ColorSpace@1c92586f transparency = 1 has alpha = false isAlphaPre = false

ColorModel после преобразования:

DirectColorModel: rmask=ff0000 gmask=ff00 bmask=ff amask=0

Спасибо!


Обновление:

Оказалось, что лучше всего работать с необработанными пиксельными данными. Поскольку TYPE_CUSTOM фактически преобразовывал RGB вручную, это просто и примерно на 95% быстрее, чем ColorConvertOp.

public static BufferedImage makeCompatible(BufferedImage img) throws IOException {
    // Allocate the new image
    BufferedImage dstImage = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_RGB);

    // Check if the ColorSpace is RGB and the TransferType is BYTE. 
    // Otherwise this fast method does not work as expected
    ColorModel cm = img.getColorModel();
    if ( cm.getColorSpace().getType() == ColorSpace.TYPE_RGB && img.getRaster().getTransferType() == DataBuffer.TYPE_BYTE ) {
        //Allocate arrays
        int len = img.getWidth()*img.getHeight();
        byte[] src = new byte[len*3];
        int[] dst = new int[len];

        // Read the src image data into the array
        img.getRaster().getDataElements(0, 0, img.getWidth(), img.getHeight(), src);

        // Convert to INT_RGB
        int j = 0;
        for ( int i=0; i<len; i++ ) {
            dst[i] = (((int)src[j++] & 0xFF) << 16) | 
                     (((int)src[j++] & 0xFF) << 8) | 
                     (((int)src[j++] & 0xFF));
        }

        // Set the dst image data
        dstImage.getRaster().setDataElements(0, 0, img.getWidth(), img.getHeight(), dst);

        return dstImage;
    }

    ColorConvertOp op = new ColorConvertOp(null);
    op.filter(img, dstImage);

    return dstImage;
}
10
задан Matt MacLean 16 January 2012 в 08:13
поделиться