ARGB int数组到CMYK字节数组转换

时间:2014-06-05 20:09:28

标签: java rgba cmyk

在这个问题:Convert RGB to CMYK中,我找到了将RGB int数组转换为CMYK字节数组的方法。现在我希望将ARGB int数组直接转换为CMYKA字节数组,而不是使用生成的CMYK数组,然后添加额外的alpha通道。有可能吗?

我尝试使用4个波段偏移来创建这样的光栅:

WritableRaster raster = Raster.createPackedRaster(db, imageWidth, imageHeight, imageWidth, new int[]{0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000}, null);

但是我收到了一个错误:源栅格波段和源颜色空间组件的数量不匹配。据我所知,源颜色空间只有3个组件。我只是想知道是否可以创建某种4组件色彩空间或其他解决方案。

这是我正在使用的当前版本:

public static byte[] RGB2CMYK(ICC_ColorSpace cmykColorSpace, int[] rgb, int imageWidth, int imageHeight, boolean hasAlpha) {
    DataBuffer db = new DataBufferInt(rgb, rgb.length);
    WritableRaster raster = Raster.createPackedRaster(db, imageWidth, imageHeight, imageWidth, new int[]{0x00ff0000, 0x0000ff00, 0x000000ff}, null);
    ColorSpace sRGB = ColorSpace.getInstance(ColorSpace.CS_sRGB);

    ColorConvertOp cco = new ColorConvertOp(sRGB, cmykColorSpace, null);

    WritableRaster cmykRaster = cco.filter(raster, null);
    byte[] cmyk = (byte[])cmykRaster.getDataElements(0, 0, imageWidth, imageHeight, null);

    if(!hasAlpha) return cmyk;

    byte[] cmyka = new byte[rgb.length*5];

    for(int i = 0, j = 0, k = 0; i < rgb.length; i++) {
        cmyka[k++] = cmyk[j++];
        cmyka[k++] = cmyk[j++];
        cmyka[k++] = cmyk[j++];
        cmyka[k++] = cmyk[j++];
        cmyka[k++] = (byte)(rgb[i]>>24 & 0xff);
    }

    return cmyka;
}

1 个答案:

答案 0 :(得分:0)

我找到了一种方法:

// Convert RGB to CMYK w/o alpha
public static byte[] RGB2CMYK(ICC_ColorSpace cmykColorSpace, int[] rgb, int imageWidth, int imageHeight, boolean hasAlpha) {
    DataBuffer db = new DataBufferInt(rgb, rgb.length);
    int[] bandMasks = new int[]{0x00ff0000, 0x0000ff00, 0x000000ff};
    ColorSpace sRGB = ColorSpace.getInstance(ColorSpace.CS_sRGB);
    ColorConvertOp cco = new ColorConvertOp(sRGB, cmykColorSpace, null);
    ColorModel cm = null;
    WritableRaster cmykRaster = null;       
    if(hasAlpha) {
        cm = ColorModel.getRGBdefault();
        bandMasks = new int[]{0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000};  
    } else 
        cm = new DirectColorModel(24, 0x00ff0000, 0x0000ff00, 0x000000ff);
    WritableRaster raster = Raster.createPackedRaster(db, imageWidth, imageHeight, imageWidth, bandMasks, null);
    BufferedImage rgbImage = new BufferedImage(cm, raster, false, null);
    BufferedImage cmykImage = cco.filter(rgbImage, null);
    cmykRaster = cmykImage.getRaster();

    return (byte[])cmykRaster.getDataElements(0, 0, imageWidth, imageHeight, null);
}

我还发现在BufferedImage而不是Raster上进行过滤是快得多。可能是一些硬件加速。