图片上传压缩

web开发中将上传图片压缩后以image类型存入数据库(转)
2009-03-11 17:45

转自http://blog.sina.com.cn/s/blog_4ce383f30100chmm.html

不久前,本人在一个小型java web项目开发中需要上传一个图片的同时,将其进行适当压缩,然后直接以image类型存入SQL Server数据库。之前,本人在网络上查找了好长时间,都没有找到合适的源码,要么就是存原图片,要么就是把图片压缩后存到服务器上,然后把相对路径以string类型存入数据库或以image类型存入数据库,本例与其不同的是,要求图片在内存中压缩后直接以image类型存入数据库。具体实现如下:

①首先,新建一个upload.jsp文件,用来选择需要上传的图片,源码如下:

<%@ page contentType="text/html; charset=gb2312" language="java"
import="java.sql.*" errorPage=""%>
<html >
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>上传并压缩图片</title>
<style>
td {
font-family: "宋体";
font-size: 12px;
}
</style>
</head>

<body>

<table border="0" align="center" cellpadding="0" cellspacing="0">

<tr>

<td height="45" align="center" valign="middle">
<form action="ImgDealServlet" method="post"
enctype="multipart/form-data" name="form1">
<table border="0" align="center" cellpadding="0" cellspacing="0">
<tr>
<td colspan="2" height="50">
<div align="center">
上传并压缩图片应用
</div>
</td>
</tr>
<tr>
<td>
请选择上传的图片
</td>
<td>
<input type="file" name="file" />
<input type="submit" name="Submit" value="上传" />
</td>
</tr>
</table>
</form>
</td>
</tr>
</table>

</body>
</html>

②然后,创建一个servlet文件ImgDealServlet.java,用来处理图片的上传,源码如下:

package servlet;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.sql.ResultSet;


import util.*;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.jspsmart.upload.SmartUpload;

public class ImgDealServlet extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {


request.setCharacterEncoding("GB2312");
response.setContentType("text/html; charset=GB2312");

PrintWriter out = response.getWriter();

SmartUpload mySmartUpload = new SmartUpload();
mySmartUpload.initialize(getServletConfig(),request,response);


try {
mySmartUpload.setAllowedFilesList("jpg,JPG,gif");
//上载文件
mySmartUpload.upload();
} catch (Exception e) {
out.print("<SCRIPT language='javascript'>");
out.print("alert('只允许上传.jpg和.gif类型图片文件');");
out.print("window.location='upfile.jsp';");
out.print("</SCRIPT>");
}
try {
com.jspsmart.upload.File myFile = mySmartUpload.getFiles().getFile(0);
// 若文件不存在
if (myFile.isMissing()) {
out.print("<SCRIPT language='javascript'>");
out.print("alert('请先选择要上传的文件');");
out.print("window.location='upfile.jsp';");
out.print("</SCRIPT>");
}
else {

String myFilePath=myFile.getFilePathName(); //取得上载的文件的路径
UploadImg ui=new UploadImg();
BufferedImage tag =ui.getResizeImg(myFilePath,400,300,true);
if(tag!=null){
ui.saveImgToDB(tag);
}
response.sendRedirect("showimg.jsp");

}
} catch (Exception e) {
e.toString();
}
}


public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

doGet(request,response);
}

}

③之前的servlet文件中用到了一个自定义包中的类UploadImg.java,其中定义了图片处理的方法,其源码如下:

package util;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import javax.imageio.ImageIO;
import util.DBConnect;

public class UploadImg {
String myFilePath = "";

public BufferedImage getResizeImg(String path, int width, int height,
boolean isResize) {

String myFilePath = path; // 取得上载的文件的路径
BufferedImage srcimg, tag;
tag = null;
int new_w; // 压缩后大小
int new_h;
boolean Resize;// 是否等比缩放

try {
srcimg = ImageIO.read(new java.io.File(myFilePath));
if (isResize) {// 等比缩放
double rate1 = ((double) srcimg.getWidth(null))
/ (double) width + 0.1;
double rate2 = ((double) srcimg.getHeight(null))
/ (double) height + 0.1;
double rate = rate1 > rate2 ? rate1 : rate2;
new_w = (int) (((double) srcimg.getWidth(null)) / rate);
new_h = (int) (((double) srcimg.getHeight(null)) / rate);
} else {
new_w = width;
new_h = height;
}
Image image = srcimg.getScaledInstance(new_w, new_h,
Image.SCALE_DEFAULT);
tag = new BufferedImage(new_w, new_h, BufferedImage.TYPE_INT_RGB);
Graphics g = tag.getGraphics();
g.drawImage(image, 0, 0, null); // 绘制缩小后的图
g.dispose();
return tag;

} catch (Exception e) {
e.printStackTrace();
}
return tag;
}

public void saveImgToDB(BufferedImage bi) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
BufferedImage tag = bi;
try {
ImageIO.write(tag, "jpg", baos);
byte[] bytes = baos.toByteArray();
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
String strsql = "update imgtest set img=? where id=1";
DBConnect dbcSelect = new DBConnect(strsql);
dbcSelect.setBinaryStream(1, bis, bytes.length);
dbcSelect.executeUpdate();
dbcSelect.close();
} catch (Exception e) {
}
}

}

④上面的Upload.java文件中同样也用到了另一个自定义的数据库连接类DBConnect.java,源码如下:

package util;

import java.io.InputStream;
import java.sql.*;

public class DBConnect {
private Connection conn = null;

private Statement stmt = null;

private PreparedStatement prepstmt = null;

public static final int JADMIS_CONNECT = 3;

public static final int FTFORDE_CONNECT = 2;

public static final int WEBSITE_CONNECT = 1;

public static final int PLATFORM_CONNECT = 0;

void init() {
try {
Class.forName("org.logicalcobwebs.proxool.ProxoolDriver");
conn = DriverManager.getConnection("proxool.mysql");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}


void init(String conName) {
try {
Class.forName("org.logicalcobwebs.proxool.ProxoolDriver");
conn = DriverManager.getConnection("proxool." + conName);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

public DBConnect(int ConnectIndex) throws SQLException {
switch (ConnectIndex) {
case JADMIS_CONNECT:
init("jadmis");
break;
case WEBSITE_CONNECT:
init("website");
break;
case PLATFORM_CONNECT:
init("mysql");
break;
case FTFORDE_CONNECT:
init("ftde");
break;
}
stmt = conn.createStatement();
}

public DBConnect(int ConnectIndex, int resultSetType,
int resultSetConcurrency) throws SQLException {
switch (ConnectIndex) {
case JADMIS_CONNECT:
init("jadmis");
break;
case WEBSITE_CONNECT:
init("website");
break;
case PLATFORM_CONNECT:
init("mysql");
break;
case FTFORDE_CONNECT:
init("ftde");
break;
}
stmt = conn.createStatement(resultSetType, resultSetConcurrency);
}


public DBConnect() throws SQLException {
init();
stmt = conn.createStatement();
}

public DBConnect(int resultSetType, int resultSetConcurrency)
throws SQLException {
init();
stmt = conn.createStatement(resultSetType, resultSetConcurrency);
}


public DBConnect(String sql) throws SQLException {
init();
this.prepareStatement(sql);
}

public DBConnect(String sql, int resultSetType, int resultSetConcurrency)
throws SQLException {
init();
this.prepareStatement(sql, resultSetType, resultSetConcurrency);
}
//added by tmw 080221
public DBConnect(int ConnectIndex,String sql) throws SQLException {
switch (ConnectIndex) {
case WEBSITE_CONNECT:
init("website");
break;
case PLATFORM_CONNECT:
init("ft");
break;
case FTFORDE_CONNECT:
init("ftde");
break;
case JADMIS_CONNECT:
init("mysql");
break;
}
this.prepareStatement(sql);
}
//added by tmw 080221
public DBConnect(int ConnectIndex,String sql, int resultSetType, int resultSetConcurrency)
throws SQLException {
switch (ConnectIndex) {
case WEBSITE_CONNECT:
init("website");
break;
case PLATFORM_CONNECT:
init("ft");
break;
case FTFORDE_CONNECT:
init("ftde");
break;
case JADMIS_CONNECT:
init("mysql");
break;
}
this.prepareStatement(sql, resultSetType, resultSetConcurrency);
}

public Connection getConnection() {
return conn;
}


public void prepareStatement(String sql) throws SQLException {
prepstmt = conn.prepareStatement(sql);
}

public void prepareStatement(String sql, int resultSetType,
int resultSetConcurrency) throws SQLException {
prepstmt = conn.prepareStatement(sql, resultSetType,
resultSetConcurrency);
}


public void setString(int index, String value) throws SQLException {
prepstmt.setString(index, value);
}

public void setInt(int index, int value) throws SQLException {
prepstmt.setInt(index, value);
}

public void setBoolean(int index, boolean value) throws SQLException {
prepstmt.setBoolean(index, value);
}

public void setDate(int index, Date value) throws SQLException {
prepstmt.setDate(index, value);
}

public void setLong(int index, long value) throws SQLException {
prepstmt.setLong(index, value);
}
//add by sch
public void setDouble(int index, double value) throws SQLException {
prepstmt.setDouble(index, value);
}
//add by sch
public void setObject(int index, Object value)throws SQLException {
prepstmt.setObject(index,value);
}
public void setFloat(int index, float value) throws SQLException {
prepstmt.setFloat(index, value);
}

public void setBytes(int index, byte[] value) throws SQLException {
prepstmt.setBytes(index, value);
}

public void setBinaryStream(int index, InputStream is, int length)
throws SQLException {
prepstmt.setBinaryStream(index, is, length);
}

public void clearParameters() throws SQLException {
prepstmt.clearParameters();
prepstmt = null;
}


public PreparedStatement getPreparedStatement() {
return prepstmt;
}


public Statement getStatement() {
return stmt;
}


public ResultSet executeQuery(String sql) throws SQLException {
if (stmt != null) {
return stmt.executeQuery(sql);
} else
return null;
}

public ResultSet executeQuery() throws SQLException {
if (prepstmt != null) {
return prepstmt.executeQuery();
} else
return null;
}


public void executeUpdate(String sql) throws SQLException {
if (stmt != null)
stmt.executeUpdate(sql);
}

public void executeUpdate() throws SQLException {
if (prepstmt != null)
prepstmt.executeUpdate();
}


public void close() throws SQLException {
if (stmt != null) {
stmt.close();
stmt = null;
}
if (prepstmt != null) {
prepstmt.close();
prepstmt = null;
}
if (conn != null) {

conn.close();
conn=null;

}
}
}

⑤此外,由于用到了proxool数据库连接池,所以需要添加proxool.xml并修改web.xml配置文件,proxool.xml源码如下:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- the proxool configuration can be embedded within your own application's.
Anything outside the "proxool" tag is ignored. -->
<something-else-entirely>
<proxool>
<alias>mysql</alias>
<driver-url>jdbc:jtds:sqlserver://localhost:1433;DatabaseName=lwjtest</driver-url>
<driver-class>net.sourceforge.jtds.jdbc.Driver</driver-class>
<driver-properties>
<property name="user" value="sa" />
<property name="password" value="sa />
</driver-properties>
<maximum-connection-count>5000</maximum-connection-count>
<minimum-connection-count>5</minimum-connection-count>
<maximum-active-time>60000</maximum-active-time>
</proxool>
</something-else-entirely>

web.xml配置文件代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<!--Connecting Pool -->
<servlet>
<servlet-name>ServletConfigurator</servlet-name>
<servlet-class>org.logicalcobwebs.proxool.configuration.ServletConfigurator</servlet-class>
<init-param>
<param-name>xmlFile</param-name>
<param-value>WEB-INF/proxool.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>Admin</servlet-name>
<servlet-class>org.logicalcobwebs.proxool.admin.servlet.AdminServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Admin</servlet-name>
<url-pattern>/admin</url-pattern>
</servlet-mapping>
<!--Connecting Pool Over -->


<servlet>
<servlet-name>ImgDealServlet</servlet-name>
<servlet-class>servlet.ImgDealServlet</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>ImgDealServlet</servlet-name>
<url-pattern>/ImgDealServlet</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>upfile.jsp</welcome-file>
</welcome-file-list>
</web-app>

⑥此外,还需要导入几个jar包,jspsmartupload.jar、jtds-1.1.jar和proxool-0.9.0RC3.jar,至于这三个包是做什么用的,我想就不用我多说了吧。

两个图片我用的都是BufferedImage类,因为不同了解流的用法,所以可能会有些不当。此外,还有一点要说明的是,如果jsp文件中字符编码格式用utf-8时,不支持图片的中文路径,改为gb2312就OK了。

由于是第一次发帖,且源码基本为本人及朋友所改写,错误及不当之处一定不少,还请大家多多指教,在此谢过!
 

你可能感兴趣的:(图片上传)