从RGB转换为CMYK的任何更快算法 [英] Any faster algorithm to transform from RGB to CMYK

查看:152
本文介绍了从RGB转换为CMYK的任何更快算法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这就是我使用更正确的"方式(即使用ICC颜色配置文件)将RGB转换为CMYK的方式.

This is how I am doing to convert from RGB to CMYK using the more "correct" way - i.e using an ICC color profile.

// Convert RGB to CMYK with level shift (minus 128)
private void RGB2CMYK(int[] rgb, float[][] C, float[][] M, float[][] Y, float[][] K, int imageWidth, int imageHeight) throws Exception {
    ColorSpace instance = new ICC_ColorSpace(ICC_Profile.getInstance(JPEGWriter.class.getResourceAsStream(pathToCMYKProfile)));
    float red, green, blue, cmyk[];
    //
    for(int i = 0, index = 0; i < imageHeight; i++) {
        for(int j = 0; j < imageWidth; j++, index++) {
            red = ((rgb[index] >> 16) & 0xff)/255.0f;
            green = ((rgb[index] >> 8) & 0xff)/255.0f;
            blue = (rgb[index] & 0xff)/255.0f;
            cmyk = instance.fromRGB(new float[] {red, green, blue});
            C[i][j] = cmyk[0]*255.0f - 128.0f;
            M[i][j] = cmyk[1]*255.0f - 128.0f;
            Y[i][j] = cmyk[2]*255.0f - 128.0f;
            K[i][j] = cmyk[3]*255.0f - 128.0f;
        }
    }
}

我的问题是:鉴于大图像,它的速度太慢了.在一种情况下,我将数据写为JPEG图像大约需要104秒而不是通常的2秒.事实证明,上述转换是最耗时的部分.

My problem is: it's prohibitively slow given a large image. In one case, it took about 104s instead of the usual 2s for me to write the data as a JPEG image. It turns out the above transform is the most time-consuming part.

我想知道是否有任何方法可以使其更快. 注意:我不会使用可以从网上找到的廉价转换算法.

I am wondering if there is any way to make it faster. Note: I am not going to use the cheap conversion algorithm one can find form the web.

更新:根据haraldK的建议,这是修订版:

Update: following haraldK's suggestion, here is the revised version:

private void RGB2CMYK(int[] rgb, float[][] C, float[][] M, float[][] Y, float[][] K, int imageWidth, int imageHeight) throws Exception {
    if(cmykColorSpace == null)
        cmykColorSpace = new ICC_ColorSpace(ICC_Profile.getInstance(JPEGWriter.class.getResourceAsStream(pathToCMYKProfile)));
    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[] o = (byte[])cmykRaster.getDataElements(0, 0, imageWidth, imageHeight, null);

    for(int i = 0, index = 0; i < imageHeight; i++) {
        for(int j = 0; j < imageWidth; j++) {
            C[i][j] = (o[index++]&0xff) - 128.0f;
            M[i][j] = (o[index++]&0xff) - 128.0f;
            Y[i][j] = (o[index++]&0xff) - 128.0f;
            K[i][j] = (o[index++]&0xff) - 128.0f;
        }
    }
}

更新:我还发现对BufferedImage而不是Raster进行过滤要快得多.看到这篇文章: ARGB int数组到CMYKA字节数组的转换

Update: I also found out it's much faster to do filter on a BufferedImage instead of a Raster. See this post: ARGB int array to CMYKA byte array convertion

推荐答案

您可能应该使用

You should probably use ColorConvertOp. It uses optimized native code on most platforms, and supports ICC profile transforms.

不确定使用基于floatRaster时它将运行多快,但是可以完成工作.

Not sure how fast it will work when using float based Rasters, but it does the job.

类似的东西:

ICC_Profile cmyk = ...;
ICC_Profile sRGB = ...;

ColorConvertOp cco = new ColorConvertOp(sRGB, cmyk);

Raster rgbRaster = ...;
WritableRaster cmykRaster = cco.filter(rgbRaster, null); 

// Or alternatively, if you have a BufferedImage input
BufferedImage rgbImage = ...;
BufferedImage cmykImage = cco.filter(rgbImage, null);

这篇关于从RGB转换为CMYK的任何更快算法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆