java ImageIO.read()中的内存泄漏
发布时间:2020-12-14 19:36:55 所属栏目:Java 来源:网络整理
导读:我正在使用 ImageIO.read().由原始App的main方法调用的类是: import java.awt.*;import javax.swing.*;import java.io.File;import java.awt.image.BufferedImage;import java.awt.event.*;import javax.swing.JPanel;class ImageGenerator extends JPanel{
我正在使用
ImageIO.read().由原始App的main方法调用的类是:
import java.awt.*; import javax.swing.*; import java.io.File; import java.awt.image.BufferedImage; import java.awt.event.*; import javax.swing.JPanel; class ImageGenerator extends JPanel{ JpegReader jpeg; public ImageGenerator(Aplicacion a){ jpeg = new JpegReader(); loadImage(); } private void loadImage(){ String path = "C:image.jpg"; image = new BufferedImage(100,100,BufferedImage.TYPE_INT_RGB); //in case error try{ image = jpeg.readImage(new File(path)); }catch(Exception e){ System.err.println(e.getMessage()); } } public void paint(Graphics g){ Graphics2D g2 = (Graphics2D) g; g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BICUBIC); g2.drawImage(image,1000,800,null); } } 我正在使用上面的这个其他类JpegReader,我实际上在StackOverflow上找到了答案,但我忘了引用他的作者的名字. import java.awt.image.BufferedImage; import javax.imageio.*; import javax.imageio.stream.ImageInputStream; import java.awt.color.*; import java.awt.image.*; import java.io.File; import java.io.IOException; import java.util.Iterator; import java.util.ArrayList; import org.apache.sanselan.Sanselan; import org.apache.sanselan.common.byteSources.ByteSource; import org.apache.sanselan.common.byteSources.ByteSourceFile; import org.apache.sanselan.ImageReadException; import org.apache.sanselan.formats.jpeg.JpegImageParser; import org.apache.sanselan.formats.jpeg.segments.UnknownSegment; public class JpegReader { public static final int COLOR_TYPE_RGB = 1; public static final int COLOR_TYPE_CMYK = 2; public static final int COLOR_TYPE_YCCK = 3; private int colorType = COLOR_TYPE_RGB; private boolean hasAdobeMarker = false; public BufferedImage readImage(File file) throws IOException,ImageReadException { colorType = COLOR_TYPE_RGB; hasAdobeMarker = false; ImageInputStream stream = ImageIO.createImageInputStream(file); Iterator<ImageReader> iter = ImageIO.getImageReaders(stream); while (iter.hasNext()) { ImageReader reader = iter.next(); reader.setInput(stream); BufferedImage image; ICC_Profile profile = null; try { image = reader.read(0); } catch (IIOException e) { System.out.println("Hello"); colorType = COLOR_TYPE_CMYK; checkAdobeMarker(file); profile = Sanselan.getICCProfile(file); WritableRaster raster = (WritableRaster) reader.readRaster(0,null); if (colorType == COLOR_TYPE_YCCK) convertYcckToCmyk(raster); if (hasAdobeMarker) convertInvertedColors(raster); image = convertCmykToRgb(raster,profile); System.out.println("Hello"); }finally { try { System.out.println("facebook"); stream.close(); } catch (IOException ioex) { //omitted. } } return image; } return null; } public void checkAdobeMarker(File file) throws IOException,ImageReadException { JpegImageParser parser = new JpegImageParser(); ByteSource byteSource = new ByteSourceFile(file); @SuppressWarnings("rawtypes") ArrayList segments = parser.readSegments(byteSource,new int[] { 0xffee },true); if (segments != null && segments.size() >= 1) { UnknownSegment app14Segment = (UnknownSegment) segments.get(0); byte[] data = app14Segment.bytes; if (data.length >= 12 && data[0] == 'A' && data[1] == 'd' && data[2] == 'o' && data[3] == 'b' && data[4] == 'e') { hasAdobeMarker = true; int transform = app14Segment.bytes[11] & 0xff; if (transform == 2) colorType = COLOR_TYPE_YCCK; } } } public static void convertYcckToCmyk(WritableRaster raster) { int height = raster.getHeight(); int width = raster.getWidth(); int stride = width * 4; int[] pixelRow = new int[stride]; for (int h = 0; h < height; h++) { raster.getPixels(0,h,width,1,pixelRow); for (int x = 0; x < stride; x += 4) { int y = pixelRow[x]; int cb = pixelRow[x + 1]; int cr = pixelRow[x + 2]; int c = (int) (y + 1.402 * cr - 178.956); int m = (int) (y - 0.34414 * cb - 0.71414 * cr + 135.95984); y = (int) (y + 1.772 * cb - 226.316); if (c < 0) c = 0; else if (c > 255) c = 255; if (m < 0) m = 0; else if (m > 255) m = 255; if (y < 0) y = 0; else if (y > 255) y = 255; pixelRow[x] = 255 - c; pixelRow[x + 1] = 255 - m; pixelRow[x + 2] = 255 - y; } raster.setPixels(0,pixelRow); } } public static void convertInvertedColors(WritableRaster raster) { int height = raster.getHeight(); int width = raster.getWidth(); int stride = width * 4; int[] pixelRow = new int[stride]; for (int h = 0; h < height; h++) { raster.getPixels(0,pixelRow); for (int x = 0; x < stride; x++) pixelRow[x] = 255 - pixelRow[x]; raster.setPixels(0,pixelRow); } } public static BufferedImage convertCmykToRgb(Raster cmykRaster,ICC_Profile cmykProfile) throws IOException { if (cmykProfile == null) cmykProfile = ICC_Profile.getInstance(JpegReader.class.getResourceAsStream("/ISOcoated_v2_300_eci.icc")); if (cmykProfile.getProfileClass() != ICC_Profile.CLASS_DISPLAY) { byte[] profileData = cmykProfile.getData(); if (profileData[ICC_Profile.icHdrRenderingIntent] == ICC_Profile.icPerceptual) { intToBigEndian(ICC_Profile.icSigDisplayClass,profileData,ICC_Profile.icHdrDeviceClass); // Header is first cmykProfile = ICC_Profile.getInstance(profileData); } } ICC_ColorSpace cmykCS = new ICC_ColorSpace(cmykProfile); BufferedImage rgbImage = new BufferedImage(cmykRaster.getWidth(),cmykRaster.getHeight(),BufferedImage.TYPE_INT_RGB); WritableRaster rgbRaster = rgbImage.getRaster(); ColorSpace rgbCS = rgbImage.getColorModel().getColorSpace(); ColorConvertOp cmykToRgb = new ColorConvertOp(cmykCS,rgbCS,null); cmykToRgb.filter(cmykRaster,rgbRaster); return rgbImage; } static void intToBigEndian(int value,byte[] array,int index) { array[index] = (byte) (value >> 24); array[index+1] = (byte) (value >> 16); array[index+2] = (byte) (value >> 8); array[index+3] = (byte) (value); } } 我正在使用sanselan-0.97-incubator.jar. 如果我大约运行这个程序31次,我将得到一个java堆空间错误,所以我怀疑我有内存泄漏. 请帮我查找内存泄漏或建议如何解决问题. 如果我正在使用的jar文件是OKAY,或者它已经过时了,请告诉我.我在查找sanselan jar文件时遇到了一些问题. 提前致谢. 解决方法
我有这个代码(JPEGReader)相同的内存问题.经过几次试验,我发现调用reader.dispose()可以解决这个问题.
我给出了我修改过的方法.希望它对你有所帮助. public BufferedImage readImage(File file) throws IOException,ImageReadException { colorType = COLOR_TYPE_RGB; hasAdobeMarker = false; ImageInputStream stream = ImageIO.createImageInputStream(file); try{ Iterator<ImageReader> iter = ImageIO.getImageReaders(stream); while (iter.hasNext()) { ImageReader reader = iter.next(); reader.setInput(stream); BufferedImage image; ICC_Profile profile = null; try { image = reader.read(0); } catch (IIOException e) { colorType = COLOR_TYPE_CMYK; checkAdobeMarker(file); profile = Sanselan.getICCProfile(file); WritableRaster raster = (WritableRaster) reader.readRaster(0,null); if (colorType == COLOR_TYPE_YCCK) convertYcckToCmyk(raster); if (hasAdobeMarker) convertInvertedColors(raster); image = convertCmykToRgb(raster,profile); return image; } finally { reader.dispose(); } } return null; } finally { if (stream != null){ stream.close(); } } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |