에서
덕분에 나는 (이 도움이 또는하지 않을 경우 나도 몰라) 비슷한 소리 ImageIO에서 API에 대한 재이의 티파니 구현에 문제가 있었다.
기본적으로, 그것은 "단일 픽셀 포장 샘플 모델"로 색상 모델을 변환합니다 : P
를이 내 코드가 아닙니다, 제가 얼마 전에 인터넷에 그것을 발견하고, 그것을 위해 더 신용을하지 나는 (내가 검색을 시도했던 곳 내가 기억하지 않습니다 두려워 해요,하지만 적절한 참조를 찾을 수 없습니다.
/*******************************************************************************
*
* It seems that SinglePixelPackedSampleModel is the only fast mode when a
* color profile is converted. This is probably a bug (that has nothing to do
* with bugs 4886071 and 4705399).
* Note that grayscale images (TYPE_GRAY) are not converted.
*
******************************************************************************/
public static BufferedImage convertToSinglePixelPackedSampleModel(BufferedImage image) {
long time = System.currentTimeMillis();
WritableRaster sourceRaster = image.getRaster();
ColorModel colorModel = image.getColorModel();
ICC_ColorSpace colorSpace = (ICC_ColorSpace) colorModel.getColorSpace();
final SampleModel ssmd = sourceRaster.getSampleModel();
if (colorSpace.getType() == ColorSpace.TYPE_GRAY) {
logger.info(">>>> TYPE_GRAY, not converting");
} else if (!(ssmd instanceof PixelInterleavedSampleModel)) {
logger.info(">>>> sourceSampleModel is " + ssmd.getClass() + ", not converting");
} else {
PixelInterleavedSampleModel sourceSampleModel = (PixelInterleavedSampleModel) ssmd;
int[] bitMasks = new int[]{0x00ff0000, 0x0000ff00, 0x000000ff};
SinglePixelPackedSampleModel sampleModel = new SinglePixelPackedSampleModel(DataBuffer.TYPE_INT, image.getWidth(),
image.getHeight(), bitMasks);
WritableRaster destRaster = Raster.createWritableRaster(sampleModel, null);
DataBufferInt destDataBuffer = (DataBufferInt) destRaster.getDataBuffer();
int[] destBuffer = destDataBuffer.getData();
int[] bandOffsets = sourceSampleModel.getBandOffsets();
for (int i = 0; i < bandOffsets.length; i++) {
bandOffsets[i] += ((-sourceRaster.getSampleModelTranslateX() * sourceSampleModel.getPixelStride())
- (sourceRaster.getSampleModelTranslateY() * sourceSampleModel.getScanlineStride()));
}
DataBuffer sourceDataBuffer = sourceRaster.getDataBuffer();
if (sourceDataBuffer instanceof DataBufferUShort) {
convertUShortDataBuffer(image, (DataBufferUShort) sourceDataBuffer, sourceSampleModel, bandOffsets, destBuffer);
} else if (sourceDataBuffer instanceof DataBufferByte) {
convertByteDataBuffer(image, (DataBufferByte) sourceDataBuffer, sourceSampleModel, bandOffsets, destBuffer);
} else {
throw new IllegalArgumentException("Cannot deal with " + sourceDataBuffer.getClass());
}
String sourceProfileName = getICCProfileName(colorSpace.getProfile());
if (sourceProfileName.equals("Nikon sRGB 4.0.0.3001")) {
logger.warn(">>>> Workaround #1094403: using sRGB instead of " + sourceProfileName);
colorSpace = new ICC_ColorSpace(ICC_Profile.getInstance(ColorSpace.CS_LINEAR_RGB));
}
colorModel = new DirectColorModel(colorSpace, 24, bitMasks[0], bitMasks[1], bitMasks[2], 0, false, DataBuffer.TYPE_INT);
image = new BufferedImage(colorModel, destRaster, false, null);
}
time = System.currentTimeMillis() - time;
logger.info(">>>> convertToSinglePixelPackedSampleModel() completed ok in " + time + " msec");
return image;
}
/**
* @param image
* @param sourceDataBuffer
* @param sourceSampleModel
* @param bandOffsets
* @param destBuffer
*/
protected static void convertByteDataBuffer(BufferedImage image, DataBufferByte sourceDataBuffer,
PixelInterleavedSampleModel sourceSampleModel, int[] bandOffsets, int[] destBuffer) {
int base = 0;
int i = 0;
byte[] sourceBuffer = sourceDataBuffer.getData();
int pixelStride = sourceSampleModel.getPixelStride();
for (int y = 0; y < image.getHeight(); y++) {
int j = base;
for (int x = 0; x < image.getWidth(); x++) {
int r = (sourceBuffer[j + bandOffsets[0]] & 0xff);
int g = (sourceBuffer[j + bandOffsets[1]] & 0xff);
int b = (sourceBuffer[j + bandOffsets[2]] & 0xff);
destBuffer[i++] = (r << 16) | (g << 8) | b;
j += pixelStride;
}
base += sourceSampleModel.getScanlineStride();
}
}
protected static void convertUShortDataBuffer(BufferedImage image, DataBufferUShort sourceDataBuffer,
PixelInterleavedSampleModel sourceSampleModel, int[] bandOffsets, int[] destBuffer) {
int base = 0;
int i = 0;
short[] sourceBuffer = sourceDataBuffer.getData();
for (int y = 0; y < image.getHeight(); y++) {
int j = base;
for (int x = 0; x < image.getWidth(); x++) {
int r = (sourceBuffer[j + bandOffsets[0]] & 0xffff) >> 8;
int g = (sourceBuffer[j + bandOffsets[1]] & 0xffff) >> 8;
int b = (sourceBuffer[j + bandOffsets[2]] & 0xffff) >> 8;
destBuffer[i++] = (r << 16) | (g << 8) | b;
j += 3;
}
base += sourceSampleModel.getScanlineStride();
}
}
// public static ICC_Profile getICCProfile(RenderedImage image) {
//
// ColorSpace colorSpace = image.getColorModel().getColorSpace();
//
// if (colorSpace instanceof ICC_ColorSpace) {
//
// ICC_ColorSpace iccColorSpace = (ICC_ColorSpace) colorSpace;
//
// return iccColorSpace.getProfile();
//
// }
//
// return null;
//
// }
public static String getICCProfileName(ICC_Profile profile) {
if (profile == null) {
return null;
}
byte[] xx = profile.getData(ICC_Profile.icSigProfileDescriptionTag);
int offset = 12;
int count;
for (count = 1; xx[offset + count] != 0; count++) {
;
}
return new String(xx, 0, offset, count);
}
기본적으로, 단지 .convertToSinglePixelPackedSampleModel(image)
를 호출합니다.
내가의 렌더링 시간이 걸렸습니다 a (상대적으로 큰 TIFF 이미지)를 몇 분에서 몇 분 미만으로 낮추십시오. conds : P
추신 - 난 내가 비슷한 문제를 가지고 원래의 코드 http://www.koders.com/java/fidFE1D69AFE6930A514D5E189310AB10A3DFD43F78.aspx
를 발견 한 곳이 생각합니다. bufferedImage는 페인트하는 것이 정말 느 렸습니다. 이것으로 해결했습니다. –