📄 colorconvertop.java
字号:
/* make the transform list */ theTransforms = new ICC_Transform [nTransforms]; /* initialize transform get loop */ if (theProfiles[0].getProfileClass() == ICC_Profile.CLASS_OUTPUT) { /* if first profile is a printer render as colorimetric */ renderState = ICC_Profile.icRelativeColorimetric; } else { renderState = ICC_Profile.icPerceptual; /* render any other class perceptually */ } whichTrans = ICC_Transform.In; /* get the transforms from each profile */ for (i1 = 0; i1 < nTransforms; i1++) { if (i1 == nTransforms -1) { /* last profile? */ whichTrans = ICC_Transform.Out; /* get output transform */ } else { /* check for abstract profile */ if ((whichTrans == ICC_Transform.Simulation) && (theProfiles[i1].getProfileClass () == ICC_Profile.CLASS_ABSTRACT)) { renderState = ICC_Profile.icPerceptual; whichTrans = ICC_Transform.In; } } theTransforms[i1] = new ICC_Transform (theProfiles[i1], renderState, whichTrans); /* get this profile's rendering intent to select transform from next profile */ renderState = getRenderingIntent(theProfiles[i1]); /* "middle" profiles use simulation transform */ whichTrans = ICC_Transform.Simulation; } /* make the net transform */ thisTransform = new ICC_Transform (theTransforms); /* update corresponding source and dest profiles */ thisSrcProfile = srcProfile; thisDestProfile = destProfile; } /** * ColorConverts the image data in the source Raster. * If the destination Raster is null, a new Raster will be created. * The number of bands in the source and destination Rasters must * meet the requirements explained above. The constructor used to * create this ColorConvertOp must have provided enough information * to define both source and destination color spaces. See above. * Otherwise, an exception is thrown. * @param src the source <code>Raster</code> to be converted * @param dest the destination <code>WritableRaster</code>, * or <code>null</code> * @return <code>dest</code> color converted from <code>src</code> * or a new, converted <code>WritableRaster</code> * if <code>dest</code> is <code>null</code> * @exception IllegalArgumentException if the number of source or * destination bands is incorrect, the source or destination * color spaces are undefined, or this op was constructed * with one of the constructors that applies only to * operations on BufferedImages. */ public final WritableRaster filter (Raster src, WritableRaster dest) { if (CSList != null) { /* non-ICC case */ return nonICCRasterFilter(src, dest); } int nProfiles = profileList.length; if (nProfiles < 2) { throw new IllegalArgumentException( "Source or Destination ColorSpace is undefined"); } if (src.getNumBands() != profileList[0].getNumComponents()) { throw new IllegalArgumentException( "Numbers of source Raster bands and source color space " + "components do not match"); } if (dest == null) { dest = createCompatibleDestRaster(src); } else { if (src.getHeight() != dest.getHeight() || src.getWidth() != dest.getWidth()) { throw new IllegalArgumentException( "Width or height of Rasters do not match"); } if (dest.getNumBands() != profileList[nProfiles-1].getNumComponents()) { throw new IllegalArgumentException( "Numbers of destination Raster bands and destination " + "color space components do not match"); } } /* make a new transform if needed */ if (thisRasterTransform == null) { int i1, whichTrans, renderState; ICC_Transform[] theTransforms; /* make the transform list */ theTransforms = new ICC_Transform [nProfiles]; /* initialize transform get loop */ if (profileList[0].getProfileClass() == ICC_Profile.CLASS_OUTPUT) { /* if first profile is a printer render as colorimetric */ renderState = ICC_Profile.icRelativeColorimetric; } else { renderState = ICC_Profile.icPerceptual; /* render any other class perceptually */ } whichTrans = ICC_Transform.In; /* get the transforms from each profile */ for (i1 = 0; i1 < nProfiles; i1++) { if (i1 == nProfiles -1) { /* last profile? */ whichTrans = ICC_Transform.Out; /* get output transform */ } else { /* check for abstract profile */ if ((whichTrans == ICC_Transform.Simulation) && (profileList[i1].getProfileClass () == ICC_Profile.CLASS_ABSTRACT)) { renderState = ICC_Profile.icPerceptual; whichTrans = ICC_Transform.In; } } theTransforms[i1] = new ICC_Transform (profileList[i1], renderState, whichTrans); /* get this profile's rendering intent to select transform from next profile */ renderState = getRenderingIntent(profileList[i1]); /* "middle" profiles use simulation transform */ whichTrans = ICC_Transform.Simulation; } /* make the net transform */ thisRasterTransform = new ICC_Transform (theTransforms); } int srcTransferType = src.getTransferType(); int dstTransferType = dest.getTransferType(); if ((srcTransferType == DataBuffer.TYPE_FLOAT) || (srcTransferType == DataBuffer.TYPE_DOUBLE) || (dstTransferType == DataBuffer.TYPE_FLOAT) || (dstTransferType == DataBuffer.TYPE_DOUBLE)) { if (srcMinVals == null) { getMinMaxValsFromProfiles(profileList[0], profileList[nProfiles-1]); } /* color convert the raster */ thisRasterTransform.colorConvert(src, dest, srcMinVals, srcMaxVals, dstMinVals, dstMaxVals); } else { /* color convert the raster */ thisRasterTransform.colorConvert(src, dest); } return dest; } /** * Returns the bounding box of the destination, given this source. * Note that this will be the same as the the bounding box of the * source. * @param src the source <code>BufferedImage</code> * @return a <code>Rectangle2D</code> that is the bounding box * of the destination, given the specified <code>src</code> */ public final Rectangle2D getBounds2D (BufferedImage src) { return getBounds2D(src.getRaster()); } /** * Returns the bounding box of the destination, given this source. * Note that this will be the same as the the bounding box of the * source. * @param src the source <code>Raster</code> * @return a <code>Rectangle2D</code> that is the bounding box * of the destination, given the specified <code>src</code> */ public final Rectangle2D getBounds2D (Raster src) { /* return new Rectangle (src.getXOffset(), src.getYOffset(), src.getWidth(), src.getHeight()); */ return src.getBounds(); } /** * Creates a zeroed destination image with the correct size and number of * bands, given this source. * @param src Source image for the filter operation. * @param destCM ColorModel of the destination. If null, an * appropriate ColorModel will be used. * @return a <code>BufferedImage</code> with the correct size and * number of bands from the specified <code>src</code>. * @throws IllegalArgumentException if <code>destCM</code> is * <code>null</code> and this <code>ColorConvertOp</code> was * created without any <code>ICC_Profile</code> or * <code>ColorSpace</code> defined for the destination */ public BufferedImage createCompatibleDestImage (BufferedImage src, ColorModel destCM) { ColorSpace cs = null;; if (destCM == null) { if (CSList == null) { /* ICC case */ int nProfiles = profileList.length; if (nProfiles == 0) { throw new IllegalArgumentException( "Destination ColorSpace is undefined"); } ICC_Profile destProfile = profileList[nProfiles - 1]; cs = new ICC_ColorSpace(destProfile); } else { /* non-ICC case */ int nSpaces = CSList.length; cs = CSList[nSpaces - 1]; } } return createCompatibleDestImage(src, destCM, cs); } private BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel destCM, ColorSpace destCS) { BufferedImage image; if (destCM == null) { ColorModel srcCM = src.getColorModel(); int nbands = destCS.getNumComponents(); boolean hasAlpha = srcCM.hasAlpha(); if (hasAlpha) { nbands += 1; } int[] nbits = new int[nbands]; for (int i = 0; i < nbands; i++) { nbits[i] = 8; } destCM = new ComponentColorModel(destCS, nbits, hasAlpha, srcCM.isAlphaPremultiplied(), srcCM.getTransparency(), DataBuffer.TYPE_BYTE); } int w = src.getWidth(); int h = src.getHeight(); image = new BufferedImage(destCM, destCM.createCompatibleWritableRaster(w, h), destCM.isAlphaPremultiplied(), null); return image; } /** * Creates a zeroed destination Raster with the correct size and number of * bands, given this source. * @param src the specified <code>Raster</code> * @return a <code>WritableRaster</code> with the correct size and number * of bands from the specified <code>src</code> * @throws IllegalArgumentException if this <code>ColorConvertOp</code> * was created without sufficient information to define the * <code>dst</code> and <code>src</code> color spaces */ public WritableRaster createCompatibleDestRaster (Raster src) { int ncomponents; if (CSList != null) { /* non-ICC case */ if (CSList.length != 2) { throw new IllegalArgumentException( "Destination ColorSpace is undefined"); } ncomponents = CSList[1].getNumComponents(); } else { /* ICC case */ int nProfiles = profileList.length; if (nProfiles < 2) { throw new IllegalArgumentException( "Destination ColorSpace is undefined"); } ncomponents = profileList[nProfiles-1].getNumComponents(); } WritableRaster dest = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, src.getWidth(), src.getHeight(), ncomponents, new Point(src.getMinX(), src.getMinY())); return dest; } /** * Returns the location of the destination point given a * point in the source. If <code>dstPt</code> is non-null, * it will be used to hold the return value. Note that * for this class, the destination point will be the same * as the source point. * @param srcPt the specified source <code>Point2D</code> * @param dstPt the destination <code>Point2D</code> * @return <code>dstPt</code> after setting its location to be * the same as <code>srcPt</code> */ public final Point2D getPoint2D (Point2D srcPt, Point2D dstPt) { if (dstPt == null) { dstPt = new Point2D.Float(); } dstPt.setLocation(srcPt.getX(), srcPt.getY()); return dstPt; } /** * Returns the RenderingIntent from the specified ICC Profile. */ private int getRenderingIntent (ICC_Profile profile) { byte[] header = profile.getData(ICC_Profile.icSigHead); int index = ICC_Profile.icHdrRenderingIntent; return (((header[index] & 0xff) << 24) | ((header[index+1] & 0xff) << 16) | ((header[index+2] & 0xff) << 8) | (header[index+3] & 0xff)); } /** * Returns the rendering hints used by this op. * @return the <code>RenderingHints</code> object of this * <code>ColorConvertOp</code> */ public final RenderingHints getRenderingHints() { return hints; } private final BufferedImage nonICCBIFilter(BufferedImage src, ColorSpace srcColorSpace, BufferedImage dst, ColorSpace dstColorSpace) { int w = src.getWidth(); int h = src.getHeight(); ICC_ColorSpace ciespace =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -