对于这次的任务,一定要写一下博文了,不然,很多人也跟着我走老路,错路,这两天我一直负责研究:
ImageIO.read()方法读取图片后重写,图片蒙上一层红色的解决办法,
先前的代码如下:
private byte[] inputStreamToThumbnailsByte(InputStream is, int width,int hight) throws IOException {
ByteArrayOutputStream os = new ByteArrayOutputStream();
Thumbnails.of(is).size(width, hight).toOutputStream(os); //直接窃取,输入很多图片的icc文件会丢失,
然后会被一层红色蒙住,图片质量大大下降
byte[] thumbImgdata = os.toByteArray();
os.close();
return thumbImgdata;
}
(上面的是原图,下面的是窃取后展示的图)
之前在网上找了很多的资料,了解到了是因为在读取图片的时候图片的ICC信息,
然后就想到换种做法读取,在网上找到了这个 http://blog.csdn.net/shixing_11/article/details/6897871 (上)
http://blog.csdn.net/shixing_11/article/details/6938468 (下)
刚开始有点兴奋,以为能解决了但是,看了里面的内容后,大失所望,因为里面接受的是本地的路径图片,然后再输出到本地,还有就是他还有配置两个比较麻烦的组件,而我要的效果呢,是直接从数据库得到图片流,然后展示到页面上(电商项目)。后面我还是尝试了配置那两个组件,但是,
在这一行
ImageInfo imgInfo = new ImageInfo(srcFileName);
老报错,原来是是web没有支持的包,晕死了。还有就是在linux上的配置组件也不相同,很是繁琐
还有其中特别要注意 Toolkit getDefaultToolkit()这个方法 。项目一运行到这里就终止了
在网上查了下,原来
Toolkit getDefaultToolkit()获取默认工具包。
如果有一个系统属性名为 "awt.toolkit",则将它看作 Toolkit 的子类的类名。
如果系统属性不存在,则使用的默认工具包是名为 "sun.awt.motif.MToolkit" 的类,它是 Abstract Window Toolkit 的主题实现。
后面还甚至想到了用Java语言实现RGB与CMYK色彩空间的转换 如下
http://www.itren.cn/bbs/html/bbs8595.html
但是这个思路是错的。
后面继续从其他地方入手,又找到这个转换图片的方法,
http://www.oschina.net/question/1092_23668
01 public static void main(String[] args) throws IOException{
02 Image img = Toolkit.getDefaultToolkit().getImage("C:\\google.jpg");
03 BufferedImage bi_scale = toBufferedImage(img);
04 ImageIO.write(bi_scale, "jpg",new File("C:\\2.jpg"));
05 }
06
07 public static BufferedImage toBufferedImage(Image image) {
08 if (image instanceof BufferedImage) {
09 return (BufferedImage)image;
10 }
11
12 // This code ensures that all the pixels in the image are loaded
13 image = new ImageIcon(image).getImage();
14
15 // Determine if the image has transparent pixels; for this method's
16 // implementation, see e661 Determining If an Image Has Transparent Pixels
17 //boolean hasAlpha = hasAlpha(image);
18
19 // Create a buffered image with a format that's compatible with the screen
20 BufferedImage bimage = null;
21 GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
22 try {
23 // Determine the type of transparency of the new buffered image
24 int transparency = Transparency.OPAQUE;
25 /* if (hasAlpha) {
26 transparency = Transparency.BITMASK;
27 }*/
28
29 // Create the buffered image
30 GraphicsDevice gs = ge.getDefaultScreenDevice();
31 GraphicsConfiguration gc = gs.getDefaultConfiguration();
32 bimage = gc.createCompatibleImage(
33 image.getWidth(null), image.getHeight(null), transparency);
34 } catch (HeadlessException e) {
35 // The system does not have a screen
36 }
37
38 if (bimage == null) {
39 // Create a buffered image using the default color model
40 int type = BufferedImage.TYPE_INT_RGB;
41 //int type = BufferedImage.TYPE_3BYTE_BGR;//by wang
42 /*if (hasAlpha) {
43 type = BufferedImage.TYPE_INT_ARGB;
44 }*/
45 bimage = new BufferedImage(image.getWidth(null), image.getHeight(null), type);
46 }
47
48 // Copy image to buffered image
49 Graphics g = bimage.createGraphics();
50
51 // Paint the image onto the buffered image
52 g.drawImage(image, 0, 0, null);
53 g.dispose();
54
55 return bimage;
56 }
但是, 其接收的是image 返回的还是image对象,转换很是麻烦,还有方法也是极其的杂乱,
这样,各种方法都尝试过了,各种转换也尝试过了,最后头都搞晕了,还让朋友帮忙想办法,最后终于想了一个好点的解决办法,
就是闲对图片流转换一遍先,然后再截图或是读取
不多说了,直接上代码
private byte[] inputStreamToThumbnailsByte(InputStream is, int width,int hight) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
try{
JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder(is); //先把流转一遍
BufferedImage image = decoder.decodeAsBufferedImage();
Builder<BufferedImage> bu = Thumbnails.of(image).size(width, hight); //再根据大小转换
ImageIO.write(image, "jpg", out);
bu.toOutputStream(out); //输出得到图片流
}catch(Exception e){
log.error(e);
}
out.close();
return out.toByteArray() ;
}
不过以上的方法,问题还是多多的,比如说效率问题,如果是大型的图片展示项目,估计不给力,还有就是有时读一些特殊色彩的图片,展示的是一张空白图片!!!!!!!
Linux上我还没测试过,不知道有没有这种问题。
通过这次的任务,真的让我感受甚深,还希望各位大师看了,有什么好办法也给我说说,让我这种菜鸟学习学习。