欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

图片上传压缩

程序员文章站 2022-03-27 18:04:43
...
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了。

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