blob 字段图片处理

近期,在给客户做一个Demo页面时,需要用Java读取Oracle中的blob图片字段并显示,在此过程中,遇到一些问题,例如:连接oracle数据库读取blob字段数据,对图片byte数据进行缩放等;特此记录,给自己备忘,给大家参考。

整个流程分为四步,连接oracle数据库 -> 读取blob图片字段 -> 对图片进行缩放 ->把图片展示在jsp页面上。

下面进行详细描述:

1. java连接Oracle

注:数据库是Oracle10g版本为10.2.0, 在数据库中,图片字段类型为BLOB。

 java中通常使用的是通过jdbc驱动来连接数据库,oracle也不例外,因此必须下载一个Oracle驱动的jdbc需要去网上进行下载,名称为 ojdbc14.jar。

下载地址为:

http://www.oracle.com/technology/software/tech/java/sqlj_jdbc/htdocs/jdbc101040.html

 下载了驱动之后,可以使用驱动里提供的接口进行连接,具体代码如下:

 

  1. import java.sql.*;  
  2. import java.io.*;  
  3.    
  4. import javax.imageio.ImageIO;  
  5. import java.awt.image.BufferedImage;  
  6. import java.awt.image.AffineTransformOp;  
  7. import java.awt.geom.AffineTransform;  
  8.    
  9. public class OracleQueryBean {  
  10.     private final String oracleDriverName = "oracle.jdbc.driver.OracleDriver";  
  11.     private Connection myConnection = null;  
  12.     /*图片表名*/  
  13.     private String strTabName;  
  14.     /*图片ID字段名*/  
  15.     private String strIDName;  
  16.     /*图片字段名*/  
  17.     private String strImgName;  
  18.     /**  
  19.      * 加载java连接Oracle的jdbc驱动  
  20.      */  
  21.     public OracleQueryBean(){  
  22.         try{  
  23.             Class.forName(oracleDriverName);  
  24.         }catch(ClassNotFoundException ex){  
  25.             System.out.println("加载jdbc驱动失败,原因:" + ex.getMessage());  
  26.         }  
  27.     }  
  28.     /**  
  29.      * 获取Oracle连接对象  
  30.      * @return Connection  
  31.      */  
  32.     public Connection getConnection(){  
  33.         try{  
  34.         //用户名+密码; 以下使用的Test就是Oracle里的表空间  
  35.         //从配置文件中读取数据库信息  
  36.         GetPara oGetPara = new GetPara();  
  37.         String strIP = oGetPara.getPara("serverip");  
  38.         String strPort = oGetPara.getPara("port");  
  39.         String strDBName = oGetPara.getPara("dbname");  
  40.         String strUser = oGetPara.getPara("user");  
  41.         String strPassword = oGetPara.getPara("password");  
  42.          
  43.         this.strTabName = oGetPara.getPara("tablename");  
  44.         this.strIDName = oGetPara.getPara("imgidname");  
  45.         this.strImgName = oGetPara.getPara("imgname");  
  46.          
  47.         String oracleUrlToConnect ="jdbc:oracle:thin:@"+strIP+":"+strPort+":"+strDBName;  
  48.             this.myConnection = DriverManager.getConnection(oracleUrlToConnect, strUser, strPassword);  
  49.         }catch(Exception ex){  
  50.             System.out.println("Can not get connection:" + ex.getMessage());  
  51.             System.out.println("请检测配置文件中的数据库信息是否正确." );  
  52.         }  
  53.         return this.myConnection;  
  54.     }  
  55. }  

 

2. 读取blob字段

在OracleQueryBean类中增加一个函数,来进行读取,具体代码如下:

  1. /**  
  2.      * 根据图片在数据库中的ID进行读取  
  3.      * @param strID  图片字段ID  
  4.      * @param w      需要缩到的宽度  
  5.      * @param h      需要缩到高度  
  6.      * @return  
  7.      */  
  8.     public byte[] GetImgByteById(String strID, int w, int h){  
  9.     //System.out.println("Get img data which id is " + nID);  
  10.     if(myConnection == null)  
  11.          this.getConnection();  
  12.     byte[] data = null;  
  13.     try {  
  14.             Statement stmt = myConnection.createStatement();  
  15.             ResultSet myResultSet = stmt.executeQuery("select " + this.strIDName + " from " + this.strTabName + " where " + this.strIDName + "=" + strID);  
  16.              
  17.             StringBuffer myStringBuffer = new StringBuffer();  
  18.             if (myResultSet.next()) {  
  19.                 java.sql.Blob blob = myResultSet.getBlob(this.strImgName);  
  20.                 InputStream inStream = blob.getBinaryStream();  
  21.                 try {  
  22.                     long nLen = blob.length();  
  23.                     int nSize = (int) nLen;  
  24.                     //System.out.println("img data size is :" + nSize);  
  25.                     data = new byte[nSize];  
  26.                     inStream.read(data);  
  27.                     inStream.close();  
  28.                 } catch (IOException e) {  
  29.                     System.out.println("获取图片数据失败,原因:" + e.getMessage());  
  30.                 }  
  31.                  
  32.                 data = ChangeImgSize(data, w, h);  
  33.             }  
  34.             System.out.println(myStringBuffer.toString());  
  35.             myConnection.commit();  
  36.             myConnection.close();  
  37.         } catch (SQLException ex) {  
  38.             System.out.println(ex.getMessage());  
  39.         }  
  40.         return data;  
  41. }  

3. 缩放图片

因为图片的大小可能不一致,但是在页面中输出的大小需要统一,所以需要

在OracleQueryBean类中增加一个函数,来进行缩放,具体代码如下:

  1. /**  
  2.      * 缩小或放大图片  
  3.      * @param data   图片的byte数据  
  4.      * @param w      需要缩到的宽度  
  5.      * @param h      需要缩到高度  
  6.      * @return       缩放后的图片的byte数据  
  7.      */  
  8.     private byte[] ChangeImgSize(byte[] data, int nw, int nh){  
  9.     byte[] newdata = null;  
  10.     try{   
  11.          BufferedImage bis = ImageIO.read(new ByteArrayInputStream(data));  
  12.             int w = bis.getWidth();  
  13.             int h = bis.getHeight();  
  14.             double sx = (double) nw / w;  
  15.             double sy = (double) nh / h;  
  16.             AffineTransform transform = new AffineTransform();  
  17.             transform.setToScale(sx, sy);  
  18.             AffineTransformOp ato = new AffineTransformOp(transform, null);  
  19.             //原始颜色  
  20.             BufferedImage bid = new BufferedImage(nw, nh, BufferedImage.TYPE_3BYTE_BGR);  
  21.             ato.filter(bis, bid);  
  22.              
  23.             //转换成byte字节  
  24.             ByteArrayOutputStream baos = new ByteArrayOutputStream();  
  25.             ImageIO.write(bid, "jpeg", baos);  
  26.             newdata = baos.toByteArray();  
  27.              
  28.     }catch(IOException e){   
  29.          e.printStackTrace();   
  30.     }   
  31.     return newdata;  
  32. }  

4. 展示在页面

页面使用OracleQueryBean来根据用户提供的图片id进行查询,在读取并进行缩放后,通过jsp页面进行展示,具体代码如下:

 

  1. <%@ page language="java" contentType="text/html;;charset=gbk" %>  
  2. <jsp:useBean id="OrcleQuery" scope="page" class="HLFtiDemo.OracleQueryBean" />  
  3. <%  
  4.     response.setContentType("image/jpeg");  
  5.     //图片在数据库中的 ID  
  6.     String strID = request.getParameter("id");  
  7.     //要缩略或放大图片的宽度  
  8.     String strWidth = request.getParameter("w");  
  9.     //要缩略或放大图片的高度  
  10.     String strHeight = request.getParameter("h");  
  11.     byte[] data = null;  
  12.     if(strID != null){  
  13.         int nWith = Integer.parseInt(strWidth);  
  14.         int nHeight = Integer.parseInt(strHeight);  
  15.         //获取图片的byte数据  
  16.         data = OrcleQuery.GetImgByteById(strID, nWith, nHeight);  
  17.         ServletOutputStream op = response.getOutputStream();         
  18.        op.write(data, 0, data.length);  
  19.        op.close();  
  20.        op = null;  
  21.         response.flushBuffer();  
  22.         //清除输出流,防止释放时被捕获异常  
  23.         out.clear();  
  24.         out = pageContext.pushBody();  
  25.     }  
  26. %>  


5. OracleQueryBean查询类的整体代码

OracleQueryBean.java文件代码如下所示:

  1. import java.sql.*;  
  2. import java.io.*;  
  3.    
  4. import javax.imageio.ImageIO;  
  5. import java.awt.image.BufferedImage;  
  6. import java.awt.image.AffineTransformOp;  
  7. import java.awt.geom.AffineTransform;  
  8.    
  9. public class OracleQueryBean {  
  10.     private final String oracleDriverName = "oracle.jdbc.driver.OracleDriver";  
  11.    
  12.     private Connection myConnection = null;  
  13.      
  14.     /*图片表名*/  
  15.     private String strTabName;  
  16.     /*图片ID字段名*/  
  17.     private String strIDName;  
  18.     /*图片字段名*/  
  19.     private String strImgName;  
  20.     /**  
  21.      * 加载java连接Oracle的jdbc驱动  
  22.      */  
  23.     public OracleQueryBean(){  
  24.         try{  
  25.             Class.forName(oracleDriverName);  
  26.         }catch(ClassNotFoundException ex){  
  27.             System.out.println("加载jdbc驱动失败,原因:" + ex.getMessage());  
  28.         }  
  29.     }  
  30.     /**  
  31.      * 获取Oracle连接对象  
  32.      * @return Connection  
  33.      */  
  34.     public Connection getConnection(){  
  35.         try{  
  36.         //用户名+密码; 以下使用的Test就是Oracle里的表空间  
  37.         //从配置文件中读取数据库信息  
  38.         GetPara oGetPara = new GetPara();  
  39.         String strIP = oGetPara.getPara("serverip");  
  40.         String strPort = oGetPara.getPara("port");  
  41.         String strDBName = oGetPara.getPara("dbname");  
  42.         String strUser = oGetPara.getPara("user");  
  43.         String strPassword = oGetPara.getPara("password");  
  44.          
  45.         this.strTabName = oGetPara.getPara("tablename");  
  46.         this.strIDName = oGetPara.getPara("imgidname");  
  47.         this.strImgName = oGetPara.getPara("imgname");  
  48.          
  49.         String oracleUrlToConnect ="jdbc:oracle:thin:@"+strIP+":"+strPort+":"+strDBName;  
  50.             this.myConnection = DriverManager.getConnection(oracleUrlToConnect, strUser, strPassword);  
  51.         }catch(Exception ex){  
  52.             System.out.println("Can not get connection:" + ex.getMessage());  
  53.             System.out.println("请检测配置文件中的数据库信息是否正确." );  
  54.         }  
  55.         return this.myConnection;  
  56.     }  
  57.     /**  
  58.      * 根据图片在数据库中的ID进行读取  
  59.      * @param strID  图片字段ID  
  60.      * @param w      需要缩到的宽度  
  61.      * @param h      需要缩到高度  
  62.      * @return       缩放后的图片的byte数据  
  63.      */  
  64.     public byte[] GetImgByteById(String strID, int w, int h){  
  65.     //System.out.println("Get img data which id is " + nID);  
  66.     if(myConnection == null)  
  67.          this.getConnection();  
  68.     byte[] data = null;  
  69.     try {  
  70.             Statement stmt = myConnection.createStatement();  
  71.             ResultSet myResultSet = stmt.executeQuery("select " + this.strIDName + " from " + this.strTabName + " where " + this.strIDName + "=" + strID);  
  72.              
  73.             StringBuffer myStringBuffer = new StringBuffer();  
  74.             if (myResultSet.next()) {  
  75.                 java.sql.Blob blob = myResultSet.getBlob(this.strImgName);  
  76.                 InputStream inStream = blob.getBinaryStream();  
  77.                 try {  
  78.                     long nLen = blob.length();  
  79.                     int nSize = (int) nLen;  
  80.                     //System.out.println("img data size is :" + nSize);  
  81.                     data = new byte[nSize];  
  82.                     inStream.read(data);  
  83.                     inStream.close();  
  84.                 } catch (IOException e) {  
  85.                     System.out.println("获取图片数据失败,原因:" + e.getMessage());  
  86.                 }  
  87.                  
  88.                 data = ChangeImgSize(data, w, h);  
  89.             }  
  90.             System.out.println(myStringBuffer.toString());  
  91.             myConnection.commit();  
  92.             myConnection.close();  
  93.         } catch (SQLException ex) {  
  94.             System.out.println(ex.getMessage());  
  95.         }  
  96.         return data;  
  97.     }  
  98.      
  99.     /**  
  100.      * 根据图片在数据库中的ID进行读取,显示原始大小的图片  
  101.      * @param    strID   图片字段ID  
  102.      * @return   读取后的图片byte数据  
  103.      */  
  104.     public byte[] GetImgByteById(String strID){  
  105.     //System.out.println("Get img data which id is " + nID);  
  106.     if(myConnection == null)  
  107.          this.getConnection();  
  108.     byte[] data = null;  
  109.     try {  
  110.             Statement stmt = myConnection.createStatement();  
  111.             ResultSet myResultSet = stmt.executeQuery("select " + this.strIDName + " from " + this.strTabName + " where " + this.strIDName + "=" + strID);  
  112.              
  113.             StringBuffer myStringBuffer = new StringBuffer();  
  114.             if (myResultSet.next()) {  
  115.                 java.sql.Blob blob = myResultSet.getBlob(this.strImgName);  
  116.                 InputStream inStream = blob.getBinaryStream();  
  117.                 try {  
  118.                     long nLen = blob.length();  
  119.                     int nSize = (int) nLen;  
  120.                     data = new byte[nSize];  
  121.                     inStream.read(data);  
  122.                     inStream.close();  
  123.                 } catch (IOException e) {  
  124.                     System.out.println("获取图片数据失败,原因:" + e.getMessage());  
  125.                 }  
  126.             }  
  127.             System.out.println(myStringBuffer.toString());  
  128.             myConnection.commit();  
  129.             myConnection.close();  
  130.         } catch (SQLException ex) {  
  131.             System.out.println(ex.getMessage());  
  132.         }  
  133.         return data;  
  134.     }  
  135.      
  136.     /**  
  137.      * 缩小或放大图片  
  138.      * @param data   图片的byte数据  
  139.      * @param w      需要缩到的宽度  
  140.      * @param h      需要缩到高度  
  141.      * @return  
  142.      */  
  143.     private byte[] ChangeImgSize(byte[] data, int nw, int nh){  
  144.     byte[] newdata = null;  
  145.     try{   
  146.          BufferedImage bis = ImageIO.read(new ByteArrayInputStream(data));  
  147.             int w = bis.getWidth();  
  148.             int h = bis.getHeight();  
  149.             double sx = (double) nw / w;  
  150.             double sy = (double) nh / h;  
  151.             AffineTransform transform = new AffineTransform();  
  152.             transform.setToScale(sx, sy);  
  153.             AffineTransformOp ato = new AffineTransformOp(transform, null);  
  154.             //原始颜色  
  155.             BufferedImage bid = new BufferedImage(nw, nh, BufferedImage.TYPE_3BYTE_BGR);  
  156.             ato.filter(bis, bid);            
  157.             //转换成byte字节  
  158.             ByteArrayOutputStream baos = new ByteArrayOutputStream();  
  159.             ImageIO.write(bid, "jpeg", baos);  
  160.             newdata = baos.toByteArray();  
  161.     }catch(IOException e){   
  162.          e.printStackTrace();   
  163.     }   
  164.     return newdata;  
  165.     }  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值