2014-06-05 5 views
0

Dans cette question: Convert RGB to CMYK, j'ai eu un moyen de convertir RGB int array en tableau d'octets CMYK. Maintenant, j'espère convertir ARGB int array en tableau d'octets CMYKA directement au lieu de travailler avec le tableau CMYK résultant et en ajoutant ensuite le canal alpha supplémentaire. C'est possible?ARGB int array à CMYKA byte array convertion

J'ai essayé d'utiliser 4 bandes de compensation pour créer la trame comme celui-ci:

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

mais je m'y suis une erreur: Nombre de sources bandes raster et des composants d'espace couleur source ne correspondent pas. Je comprends que cela vient du fait que l'espace de couleur source n'a que 3 composantes. Je me demande simplement s'il est possible de créer une sorte d'espace colorimétrique à 4 composants ou quelque chose pour contourner ce problème.

Ceci est la version actuelle, je travaille avec:

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

Répondre

0

J'ai trouvé un moyen de le faire:

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

J'ai aussi découvert qu'il est beaucoup plus rapide à faire filtre un BufferedImage au lieu d'un raster. Peut-être une accélération matérielle.