对于这次的任务,一定要写一下博文了,不然,很多人也跟着我走老路,错路,这两天我一直负责研究:

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;

}


 

 


 

ImageIO.read()方法读取,截取图片后重写,图片蒙上一层红色的解决 后感_ImageIO.read() 图片蒙上红

 

 

 

ImageIO.read()方法读取,截取图片后重写,图片蒙上一层红色的解决 后感_ImageIO.read() 图片蒙上红_02

(上面的是原图,下面的是窃取后展示的图)

 

 

之前在网上找了很多的资料,了解到了是因为在读取图片的时候图片的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语言实现RGBCMYK色彩空间的转换 如下

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 p_w_picpath) {

08         if (p_w_picpath instanceof BufferedImage) {

09             return (BufferedImage)p_w_picpath;

10          }

11      

12         // This code ensures that all the pixels in the p_w_picpath are loaded

13          p_w_picpath = new ImageIcon(p_w_picpath).getImage();

14      

15         // Determine if the p_w_picpath has transparent pixels; for this method's

16         // implementation, see e661 Determining If an Image Has Transparent Pixels

17         //boolean hasAlpha = hasAlpha(p_w_picpath);

18      

19         // Create a buffered p_w_picpath with a format that's compatible with the screen

20          BufferedImage bp_w_picpath = null;

21          GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();

22         try {

23             // Determine the type of transparency of the new buffered p_w_picpath

24             int transparency = Transparency.OPAQUE;

25            /* if (hasAlpha) {

26                  transparency = Transparency.BITMASK;

27              }*/

28      

29             // Create the buffered p_w_picpath

30              GraphicsDevice gs = ge.getDefaultScreenDevice();

31              GraphicsConfiguration gc = gs.getDefaultConfiguration();

32              bp_w_picpath = gc.createCompatibleImage(

33                  p_w_picpath.getWidth(null), p_w_picpath.getHeight(null), transparency);

34          } catch (HeadlessException e) {

35             // The system does not have a screen

36          }

37      

38         if (bp_w_picpath == null) {

39             // Create a buffered p_w_picpath 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              bp_w_picpath = new BufferedImage(p_w_picpath.getWidth(null), p_w_picpath.getHeight(null), type);

46          }

47      

48         // Copy p_w_picpath to buffered p_w_picpath

49          Graphics g = bp_w_picpath.createGraphics();

50      

51         // Paint the p_w_picpath onto the buffered p_w_picpath

52          g.drawImage(p_w_picpath, 0, 0, null);

53          g.dispose();

54      

55         return bp_w_picpath;

56      }

但是, 其接收的是p_w_picpath 返回的还是p_w_picpath对象,转换很是麻烦,还有方法也是极其的杂乱,

这样,各种方法都尝试过了,各种转换也尝试过了,最后头都搞晕了,还让朋友帮忙想办法,最后终于想了一个好点的解决办法,

就是闲对图片流转换一遍先,然后再截图或是读取

不多说了,直接上代码

 

private byte[] inputStreamToThumbnailsByte(InputStream is, int width,int hight) throws IOException {

    ByteArrayOutputStream out = new ByteArrayOutputStream();

    try{

     JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder(is); //先把流转一遍

     BufferedImage p_w_picpath = decoder.decodeAsBufferedImage();

     Builder<BufferedImage> bu = Thumbnails.of(p_w_picpath).size(width, hight); //再根据大小转换

     ImageIO.write(p_w_picpath, "jpg", out);

     bu.toOutputStream(out); //输出得到图片流

    }catch(Exception  e){

      log.error(e);

    }

    out.close();

    return  out.toByteArray() ;  

  }

 

不过以上的方法,问题还是多多的,比如说效率问题,如果是大型的图片展示项目,估计不给力,还有就是有时读一些特殊色彩的图片,展示的是一张空白图片!!!!!!!

Linux上我还没测试过,不知道有没有这种问题。

通过这次的任务,真的让我感受甚深,还希望各位大师看了,有什么好办法也给我说说,让我这种菜鸟学习学习。