读取 blob 图片 显示在网页(转)

先前在做项目时也对图片做过处理,只是后来换了应用服务器平台之后发现不少问题,于是进行深入学习,摸索出了这么些东西。

1.图片存储

在图片的存储字段方面,SQL Server和My SQL都有相应的字段,而在Oracle里没有明确的字段,但也提供了几个大型字段,一般,我们存储在BLOB类型里。这里有个CLOB和BLOB字段的讨论,网上学习之后知道,BLOB存储的是二进制流,而CLOB存储的是大容量的字符串,当然就应该由BLOB来承担重任了。

2.读取

BLOB的读取也是一麻烦事,在不同平台上的读取不就不一样,这个在我的csdn里有详细介绍

3.生成图片

这是想写的重点。上次有朋友在群里问过,图片生成质量不好,其实图片的生成有好多种方法。下面一一给出代码

(1)最复杂但生成图片质量较好的方法

  BLOB  blob =(BLOB)rs.getObject("fimage");     //这是在Tomcat环境下取BLOB的值

//Blob blob=rs.getBlob("fimage");                // 这是在weblogic环境下取BLOB的值
  InputStream in=blob.getBinaryStream();         //生成输入流
  BufferedImage bimage = null;                   // 缓存图片对象
  BufferedInputStream ins = new BufferedInputStream(in);       //生成缓存输入流
  bimage=ImageIO.read(ins);                      //由ImageIO对象读成缓存图片对象。ImageIO是个很重要的对象


  ServletOutputStream sos = response.getOutputStream();      //取得输出流,这里是把图片输出到客户端,如果想把图片生成本地图片文件可以这样

//FileOutputStream sos=new FileOutputStream(new File("C:/cs.jpg"));
  BufferedOutputStream bos = new BufferedOutputStream(sos);    //生成输出缓存
  JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(bos);  //生成JPEG图片对象
  encoder.encode(bimage);                         //按格式把图片流进行编码
  bos.close();
  sos.close();
这种图片生成方式麻烦一些,在页面还要做个引用或者把这段代码直接写在页面上



(2)直接ImageIO对象写出来

  BLOB  blob =(BLOB)rs.getObject("fimage");    

//Blob blob=rs.getBlob("fimage");                

  InputStream in=blob.getBinaryStream();        

  BufferedImage bimage = null;                  

  BufferedInputStream ins = new BufferedInputStream(in);      

  bimage=ImageIO.read(ins);    

  ImageIO.write(bimage,"JPEG",response.getOutputStream());    //主要的是这句,直接就把图片画出来了,但图片质量并不太好,一般在做网页识别码时用,第二个参数可以设置图片的类型,第三个参数为输出对象,这里也可以换成在本地生成图片文件,只需把文件流改写成new FileOutputStream(new File("C:/cs.jpg"))

(3)以文件流读写的方式直接输出

   BLOB  blob =(BLOB)rs.getObject("fimage");    

  //Blob blob=rs.getBlob("fimage");                

   InputStream in=blob.getBinaryStream();   

    response.setContentType("image/jpeg");
    BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream());
    int n;
    while ((n=in.read())!=-1){
    bos.write(n);
    }
    bos.flush();
    bos.close();
    in.close();

这种方式没有进行过多探讨,但这种方式输出是成功的,我个人觉得似乎有些别扭,所以不用



还有中方式,在做web图片输出的时候可以用response.write()的方式写出,但具体怎样我也不太清楚,是同事告诉可以行得通的一种方式。



4.图片的操作

先前我有些图片从网上宕下来是倒置的,入库前想正过来,因为先前的项目设计没想到这些,为了不增加额外工作,于是想找方法把倒置图片正过来,有两种方法

(1)在网页上输出时用css做处理
<img src="1483013.jpg" style="FILTER: FlipV(color=silver)">

(2)用程序把图片正过来

在网上搜了半天,终于搜到一个高手写的三个操作图片的方法,试了试,很不错,有些地方进行了修改,很可惜忘记了这个高手的出处,在此感谢一下,借用。


    public static BufferedImage resizeImage(final BufferedImage bufferedimage,
            final int w, final int h,final boolean flg){
        int type = bufferedimage.getColorModel().getTransparency();
        BufferedImage img;
        Graphics2D graphics2d;
        if(flg){
         int wg = bufferedimage.getWidth();
            int hg = bufferedimage.getHeight();
            if(wg>w||hg>h){
             (graphics2d = (img = new BufferedImage(w, h, type)).createGraphics())
              .setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BILINEAR);
                graphics2d.drawImage(bufferedimage,0,0,w,h, null); 
            }else{
             (graphics2d = (img = new BufferedImage(wg, hg, type)).createGraphics())
              .setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BILINEAR);
                graphics2d.drawImage(bufferedimage,0,0,wg,hg,null); 
             }
        }else{
         (graphics2d = (img = new BufferedImage(w, h, type)).createGraphics())
          .setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            graphics2d.drawImage(bufferedimage,0,0,w,h, null); 
        }
        graphics2d.dispose();
        return img;
    }


public static BufferedImage rotateImage(final BufferedImage bufferedimage,final int degree){
        int w = bufferedimage.getWidth();
        int h = bufferedimage.getHeight();
        int type = bufferedimage.getColorModel().getTransparency();
        BufferedImage img;
        Graphics2D graphics2d;
        (graphics2d = (img = new BufferedImage(w, h, type))
                .createGraphics()).setRenderingHint(
                RenderingHints.KEY_INTERPOLATION,
                RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        graphics2d.rotate(Math.toRadians(degree), w / 2, h / 2);
        graphics2d.drawImage(bufferedimage, 0, 0, null);
        graphics2d.dispose();
        return img;
    }



public static BufferedImage flipImage(final BufferedImage bufferedimage){
        int w = bufferedimage.getWidth();
        int h = bufferedimage.getHeight();
        BufferedImage img;
        Graphics2D graphics2d;
        (graphics2d = (img = new BufferedImage(w, h, bufferedimage.
          getColorModel().getTransparency())).createGraphics())
                .drawImage(bufferedimage, 0, 0, w, h, w, 0, 0, h, null);
        graphics2d.dispose();
        return img;
    }



这三个方法很简单的就把图片给正过来了,其实这些方法还有些缺陷,可以根据自己的用处进行更改。

纵观操作图片的方法,其主要在于BufferedImage对象的初始化和getGraphics().drawImage()的参数,搞清楚 drawImage()参数不同的各中处理,比如:

image=new BufferedImage(w,h, BufferedImage.TYPE_INT_RGB);
image.getGraphics().drawImage(bimage,0,0,200, 100, null);  //缩小图片200*100

image.getGraphics().drawImage(bimage,200, 100, null);  //截取图片200*100

等等操作。



其实图片的处理对于程序员来说是基本功,我只想是想写出我的思想上的理解,一方面怕忘记了,一方面也可以给别人给参照,有错误的地方希望高手能指出,虚心求教。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值
>