📄 colorconvertop.java
字号:
(ICC_ColorSpace) ColorSpace.getInstance(ColorSpace.CS_CIEXYZ); if (dst == null) { dst = createCompatibleDestImage(src, null); dstColorSpace = dst.getColorModel().getColorSpace(); } else { if ((h != dst.getHeight()) || (w != dst.getWidth())) { throw new IllegalArgumentException( "Width or height of BufferedImages do not match"); } } Raster srcRas = src.getRaster(); WritableRaster dstRas = dst.getRaster(); ColorModel srcCM = src.getColorModel(); ColorModel dstCM = dst.getColorModel(); int srcNumComp = srcCM.getNumColorComponents(); int dstNumComp = dstCM.getNumColorComponents(); boolean dstHasAlpha = dstCM.hasAlpha(); boolean needSrcAlpha = srcCM.hasAlpha() && dstHasAlpha; ColorSpace[] list; if ((CSList == null) && (profileList.length != 0)) { /* possible non-ICC src, some profiles, possible non-ICC dst */ boolean nonICCSrc, nonICCDst; ICC_Profile srcProfile, dstProfile; if (!(srcColorSpace instanceof ICC_ColorSpace)) { nonICCSrc = true; srcProfile = ciespace.getProfile(); } else { nonICCSrc = false; srcProfile = ((ICC_ColorSpace) srcColorSpace).getProfile(); } if (!(dstColorSpace instanceof ICC_ColorSpace)) { nonICCDst = true; dstProfile = ciespace.getProfile(); } else { nonICCDst = false; dstProfile = ((ICC_ColorSpace) dstColorSpace).getProfile(); } /* make a new transform if needed */ if ((thisTransform == null) || (thisSrcProfile != srcProfile) || (thisDestProfile != dstProfile) ) { updateBITransform(srcProfile, dstProfile); } // process per scanline float maxNum = 65535.0f; // use 16-bit precision in CMM ColorSpace cs; int iccSrcNumComp; if (nonICCSrc) { cs = ciespace; iccSrcNumComp = 3; } else { cs = srcColorSpace; iccSrcNumComp = srcNumComp; } float[] srcMinVal = new float[iccSrcNumComp]; float[] srcInvDiffMinMax = new float[iccSrcNumComp]; for (int i = 0; i < srcNumComp; i++) { srcMinVal[i] = cs.getMinValue(i); srcInvDiffMinMax[i] = maxNum / (cs.getMaxValue(i) - srcMinVal[i]); } int iccDstNumComp; if (nonICCDst) { cs = ciespace; iccDstNumComp = 3; } else { cs = dstColorSpace; iccDstNumComp = dstNumComp; } float[] dstMinVal = new float[iccDstNumComp]; float[] dstDiffMinMax = new float[iccDstNumComp]; for (int i = 0; i < dstNumComp; i++) { dstMinVal[i] = cs.getMinValue(i); dstDiffMinMax[i] = (cs.getMaxValue(i) - dstMinVal[i]) / maxNum; } float[] dstColor; if (dstHasAlpha) { int size = ((dstNumComp + 1) > 3) ? (dstNumComp + 1) : 3; dstColor = new float[size]; } else { int size = (dstNumComp > 3) ? dstNumComp : 3; dstColor = new float[size]; } short[] srcLine = new short[w * iccSrcNumComp]; short[] dstLine = new short[w * iccDstNumComp]; Object pixel; float[] color; float[] alpha = null; if (needSrcAlpha) { alpha = new float[w]; } int idx; // process each scanline for (int y = 0; y < h; y++) { // convert src scanline pixel = null; color = null; idx = 0; for (int x = 0; x < w; x++) { pixel = srcRas.getDataElements(x, y, pixel); color = srcCM.getNormalizedComponents(pixel, color, 0); if (needSrcAlpha) { alpha[x] = color[srcNumComp]; } if (nonICCSrc) { color = srcColorSpace.toCIEXYZ(color); } for (int i = 0; i < iccSrcNumComp; i++) { srcLine[idx++] = (short) ((color[i] - srcMinVal[i]) * srcInvDiffMinMax[i] + 0.5f); } } // color convert srcLine to dstLine thisTransform.colorConvert(srcLine, dstLine); // convert dst scanline pixel = null; idx = 0; for (int x = 0; x < w; x++) { for (int i = 0; i < iccDstNumComp; i++) { dstColor[i] = ((float) (dstLine[idx++] & 0xffff)) * dstDiffMinMax[i] + dstMinVal[i]; } if (nonICCDst) { color = srcColorSpace.fromCIEXYZ(dstColor); for (int i = 0; i < dstNumComp; i++) { dstColor[i] = color[i]; } } if (needSrcAlpha) { dstColor[dstNumComp] = alpha[x]; } else if (dstHasAlpha) { dstColor[dstNumComp] = 1.0f; } pixel = dstCM.getDataElements(dstColor, 0, pixel); dstRas.setDataElements(x, y, pixel); } } } else { /* possible non-ICC src, possible CSList, possible non-ICC dst */ // process per pixel int numCS; if (CSList == null) { numCS = 0; } else { numCS = CSList.length; } float[] dstColor; if (dstHasAlpha) { dstColor = new float[dstNumComp + 1]; } else { dstColor = new float[dstNumComp]; } Object spixel = null; Object dpixel = null; float[] color = null; float[] tmpColor; // process each pixel for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { spixel = srcRas.getDataElements(x, y, spixel); color = srcCM.getNormalizedComponents(spixel, color, 0); tmpColor = srcColorSpace.toCIEXYZ(color); for (int i = 0; i < numCS; i++) { tmpColor = CSList[i].fromCIEXYZ(tmpColor); tmpColor = CSList[i].toCIEXYZ(tmpColor); } tmpColor = dstColorSpace.fromCIEXYZ(tmpColor); for (int i = 0; i < dstNumComp; i++) { dstColor[i] = tmpColor[i]; } if (needSrcAlpha) { dstColor[dstNumComp] = color[srcNumComp]; } else if (dstHasAlpha) { dstColor[dstNumComp] = 1.0f; } dpixel = dstCM.getDataElements(dstColor, 0, dpixel); dstRas.setDataElements(x, y, dpixel); } } } return dst; } /* color convert a Raster - handles byte, ushort, int, short, float, or double transferTypes */ private final WritableRaster nonICCRasterFilter(Raster src, WritableRaster dst) { if (CSList.length != 2) { throw new IllegalArgumentException( "Destination ColorSpace is undefined"); } if (src.getNumBands() != CSList[0].getNumComponents()) { throw new IllegalArgumentException( "Numbers of source Raster bands and source color space " + "components do not match"); } if (dst == null) { dst = createCompatibleDestRaster(src); } else { if (src.getHeight() != dst.getHeight() || src.getWidth() != dst.getWidth()) { throw new IllegalArgumentException( "Width or height of Rasters do not match"); } if (dst.getNumBands() != CSList[1].getNumComponents()) { throw new IllegalArgumentException( "Numbers of destination Raster bands and destination " + "color space components do not match"); } } if (srcMinVals == null) { getMinMaxValsFromColorSpaces(CSList[0], CSList[1]); } SampleModel srcSM = src.getSampleModel(); SampleModel dstSM = dst.getSampleModel(); boolean srcIsFloat, dstIsFloat; int srcTransferType = src.getTransferType(); int dstTransferType = dst.getTransferType(); if ((srcTransferType == DataBuffer.TYPE_FLOAT) || (srcTransferType == DataBuffer.TYPE_DOUBLE)) { srcIsFloat = true; } else { srcIsFloat = false; } if ((dstTransferType == DataBuffer.TYPE_FLOAT) || (dstTransferType == DataBuffer.TYPE_DOUBLE)) { dstIsFloat = true; } else { dstIsFloat = false; } int w = src.getWidth(); int h = src.getHeight(); int srcNumBands = src.getNumBands(); int dstNumBands = dst.getNumBands(); float[] srcScaleFactor = null; float[] dstScaleFactor = null; if (!srcIsFloat) { srcScaleFactor = new float[srcNumBands]; for (int i = 0; i < srcNumBands; i++) { if (srcTransferType == DataBuffer.TYPE_SHORT) { srcScaleFactor[i] = (srcMaxVals[i] - srcMinVals[i]) / 32767.0f; } else { srcScaleFactor[i] = (srcMaxVals[i] - srcMinVals[i]) / ((float) ((1 << srcSM.getSampleSize(i)) - 1)); } } } if (!dstIsFloat) { dstScaleFactor = new float[dstNumBands]; for (int i = 0; i < dstNumBands; i++) { if (dstTransferType == DataBuffer.TYPE_SHORT) { dstScaleFactor[i] = 32767.0f / (dstMaxVals[i] - dstMinVals[i]); } else { dstScaleFactor[i] = ((float) ((1 << dstSM.getSampleSize(i)) - 1)) / (dstMaxVals[i] - dstMinVals[i]); } } } int ys = src.getMinY(); int yd = dst.getMinY(); int xs, xd; float sample; float[] color = new float[srcNumBands]; float[] tmpColor; ColorSpace srcColorSpace = CSList[0]; ColorSpace dstColorSpace = CSList[1]; // process each pixel for (int y = 0; y < h; y++, ys++, yd++) { // get src scanline xs = src.getMinX(); xd = dst.getMinX(); for (int x = 0; x < w; x++, xs++, xd++) { for (int i = 0; i < srcNumBands; i++) { sample = src.getSampleFloat(xs, ys, i); if (!srcIsFloat) { sample = sample * srcScaleFactor[i] + srcMinVals[i]; } color[i] = sample; } tmpColor = srcColorSpace.toCIEXYZ(color); tmpColor = dstColorSpace.fromCIEXYZ(tmpColor); for (int i = 0; i < dstNumBands; i++) { sample = tmpColor[i]; if (!dstIsFloat) { sample = (sample - dstMinVals[i]) * dstScaleFactor[i]; } dst.setSample(xd, yd, i, sample); } } } return dst; } private void getMinMaxValsFromProfiles(ICC_Profile srcProfile, ICC_Profile dstProfile) { int type = srcProfile.getColorSpaceType(); int nc = srcProfile.getNumComponents(); srcMinVals = new float[nc]; srcMaxVals = new float[nc]; setMinMax(type, nc, srcMinVals, srcMaxVals); type = dstProfile.getColorSpaceType(); nc = dstProfile.getNumComponents(); dstMinVals = new float[nc]; dstMaxVals = new float[nc]; setMinMax(type, nc, dstMinVals, dstMaxVals); } private void setMinMax(int type, int nc, float[] minVals, float[] maxVals) { if (type == ColorSpace.TYPE_Lab) { minVals[0] = 0.0f; // L maxVals[0] = 100.0f; minVals[1] = -128.0f; // a maxVals[1] = 127.0f; minVals[2] = -128.0f; // b maxVals[2] = 127.0f; } else if (type == ColorSpace.TYPE_XYZ) { minVals[0] = minVals[1] = minVals[2] = 0.0f; // X, Y, Z maxVals[0] = maxVals[1] = maxVals[2] = 1.0f + (32767.0f/ 32768.0f); } else { for (int i = 0; i < nc; i++) { minVals[i] = 0.0f; maxVals[i] = 1.0f; } } } private void getMinMaxValsFromColorSpaces(ColorSpace srcCspace, ColorSpace dstCspace) { int nc = srcCspace.getNumComponents(); srcMinVals = new float[nc]; srcMaxVals = new float[nc]; for (int i = 0; i < nc; i++) { srcMinVals[i] = srcCspace.getMinValue(i); srcMaxVals[i] = srcCspace.getMaxValue(i); } nc = dstCspace.getNumComponents(); dstMinVals = new float[nc]; dstMaxVals = new float[nc]; for (int i = 0; i < nc; i++) { dstMinVals[i] = dstCspace.getMinValue(i); dstMaxVals[i] = dstCspace.getMaxValue(i); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -