论坛首页 Java企业应用论坛

上传图片并生成缩略图

浏览 35286 次
精华帖 (1) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-12-23  
gif4j要购买的吧。。。
0 请登录后投票
   发表时间:2007-12-24  
用ImageMagick不好吗?这么麻烦
0 请登录后投票
   发表时间:2007-12-24  
lszone 写道
用ImageMagick不好吗?这么麻烦

同意。。。一般有这个要求的项目都用它。ImageMagick支持一些简单图片操作
0 请登录后投票
   发表时间:2007-12-25  
在csdn上看到一篇文章,写到一个生成缩略图的方法,试用了一下,还不错,唯一的缺点就是不能处理gif的动画,对于gif的动画,只会产生对应的静态图片
reference:http://topic.csdn.net/t/20060603/15/4798174.html

处理图片代码:
package Image;

import java.awt.image.BufferedImage;

public class ScaleImage {
	private int width;

	private int height;

	private int scaleWidth;

	private double support = (double) 3.0;

	private double PI = (double) 3.14159265358978;

	private double[] contrib;

	private double[] normContrib;

	private double[] tmpContrib;

	private int startContrib, stopContrib;

	private int nDots;

	private int nHalfDots;

	/**
	 * Start: Use Lanczos filter to replace the original algorithm for image
	 * scaling. Lanczos improves quality of the scaled image modify by :blade
	 */
	private static ScaleImage instance = new ScaleImage();
	private ScaleImage(){};
	public static ScaleImage getInstance(){
		return instance;
	}
	public BufferedImage imageZoomOut(BufferedImage srcBufferImage, int w, int h) {
		width = srcBufferImage.getWidth();
		height = srcBufferImage.getHeight();
		scaleWidth = w;

		if (DetermineResultSize(w, h) == 1) {
			return srcBufferImage;
		}
		CalContrib();
		BufferedImage pbOut = HorizontalFiltering(srcBufferImage, w);
		BufferedImage pbFinalOut = VerticalFiltering(pbOut, h);
		return pbFinalOut;
	}

	/**
	 * 决定图像尺寸
	 */
	private int DetermineResultSize(int w, int h) {
		double scaleH, scaleV;
		scaleH = (double) w / (double) width;
		scaleV = (double) h / (double) height;
		// 需要判断一下scaleH,scaleV,不做放大操作
		if (scaleH >= 1.0 && scaleV >= 1.0) {
			return 1;
		}
		return 0;

	} // end of DetermineResultSize()

	private double Lanczos(int i, int inWidth, int outWidth, double Support) {
		double x;

		x = (double) i * (double) outWidth / (double) inWidth;

		return Math.sin(x * PI) / (x * PI) * Math.sin(x * PI / Support)
				/ (x * PI / Support);

	} // end of Lanczos()

	//  
	// Assumption: same horizontal and vertical scaling factor
	//  
	private void CalContrib() {
		nHalfDots = (int) ((double) width * support / (double) scaleWidth);
		nDots = nHalfDots * 2 + 1;
		try {
			contrib = new double[nDots];
			normContrib = new double[nDots];
			tmpContrib = new double[nDots];
		} catch (Exception e) {
			System.out.println("init   contrib,normContrib,tmpContrib" + e);
		}

		int center = nHalfDots;
		contrib[center] = 1.0;

		double weight = 0.0;
		int i = 0;
		for (i = 1; i <= center; i++) {
			contrib[center + i] = Lanczos(i, width, scaleWidth, support);
			weight += contrib[center + i];
		}

		for (i = center - 1; i >= 0; i--) {
			contrib[i] = contrib[center * 2 - i];
		}

		weight = weight * 2 + 1.0;

		for (i = 0; i <= center; i++) {
			normContrib[i] = contrib[i] / weight;
		}

		for (i = center + 1; i < nDots; i++) {
			normContrib[i] = normContrib[center * 2 - i];
		}
	} // end of CalContrib()

	// 处理边缘
	private void CalTempContrib(int start, int stop) {
		double weight = 0;

		int i = 0;
		for (i = start; i <= stop; i++) {
			weight += contrib[i];
		}

		for (i = start; i <= stop; i++) {
			tmpContrib[i] = contrib[i] / weight;
		}

	} // end of CalTempContrib()

	private int GetRedValue(int rgbValue) {
		int temp = rgbValue & 0x00ff0000;
		return temp >> 16;
	}

	private int GetGreenValue(int rgbValue) {
		int temp = rgbValue & 0x0000ff00;
		return temp >> 8;
	}

	private int GetBlueValue(int rgbValue) {
		return rgbValue & 0x000000ff;
	}

	private int ComRGB(int redValue, int greenValue, int blueValue) {

		return (redValue << 16) + (greenValue << 8) + blueValue;
	}

	// 行水平滤波
	private int HorizontalFilter(BufferedImage bufImg, int startX, int stopX,
			int start, int stop, int y, double[] pContrib) {
		double valueRed = 0.0;
		double valueGreen = 0.0;
		double valueBlue = 0.0;
		int valueRGB = 0;
		int i, j;

		for (i = startX, j = start; i <= stopX; i++, j++) {
			valueRGB = bufImg.getRGB(i, y);

			valueRed += GetRedValue(valueRGB) * pContrib[j];
			valueGreen += GetGreenValue(valueRGB) * pContrib[j];
			valueBlue += GetBlueValue(valueRGB) * pContrib[j];
		}

		valueRGB = ComRGB(Clip((int) valueRed), Clip((int) valueGreen),
				Clip((int) valueBlue));
		return valueRGB;

	} // end of HorizontalFilter()

	// 图片水平滤波
	private BufferedImage HorizontalFiltering(BufferedImage bufImage, int iOutW) {
		int dwInW = bufImage.getWidth();
		int dwInH = bufImage.getHeight();
		int value = 0;
		BufferedImage pbOut = new BufferedImage(iOutW, dwInH,
				BufferedImage.TYPE_INT_RGB);

		for (int x = 0; x < iOutW; x++) {

			int startX;
			int start;
			int X = (int) (((double) x) * ((double) dwInW) / ((double) iOutW) + 0.5);
			int y = 0;

			startX = X - nHalfDots;
			if (startX < 0) {
				startX = 0;
				start = nHalfDots - X;
			} else {
				start = 0;
			}

			int stop;
			int stopX = X + nHalfDots;
			if (stopX > (dwInW - 1)) {
				stopX = dwInW - 1;
				stop = nHalfDots + (dwInW - 1 - X);
			} else {
				stop = nHalfDots * 2;
			}

			if (start > 0 || stop < nDots - 1) {
				CalTempContrib(start, stop);
				for (y = 0; y < dwInH; y++) {
					value = HorizontalFilter(bufImage, startX, stopX, start,
							stop, y, tmpContrib);
					pbOut.setRGB(x, y, value);
				}
			} else {
				for (y = 0; y < dwInH; y++) {
					value = HorizontalFilter(bufImage, startX, stopX, start,
							stop, y, normContrib);
					pbOut.setRGB(x, y, value);
				}
			}
		}

		return pbOut;

	} // end of HorizontalFiltering()

	private int VerticalFilter(BufferedImage pbInImage, int startY, int stopY,
			int start, int stop, int x, double[] pContrib) {
		double valueRed = 0.0;
		double valueGreen = 0.0;
		double valueBlue = 0.0;
		int valueRGB = 0;
		int i, j;

		for (i = startY, j = start; i <= stopY; i++, j++) {
			valueRGB = pbInImage.getRGB(x, i);

			valueRed += GetRedValue(valueRGB) * pContrib[j];
			valueGreen += GetGreenValue(valueRGB) * pContrib[j];
			valueBlue += GetBlueValue(valueRGB) * pContrib[j];
			// System.out.println(valueRed+"->"+Clip((int)valueRed)+"<-");
			//  
			// System.out.println(valueGreen+"->"+Clip((int)valueGreen)+"<-");
			// System.out.println(valueBlue+"->"+Clip((int)valueBlue)+"<-"+"-->");
		}

		valueRGB = ComRGB(Clip((int) valueRed), Clip((int) valueGreen),
				Clip((int) valueBlue));
		// System.out.println(valueRGB);
		return valueRGB;

	} // end of VerticalFilter()

	private BufferedImage VerticalFiltering(BufferedImage pbImage, int iOutH) {
		int iW = pbImage.getWidth();
		int iH = pbImage.getHeight();
		int value = 0;
		BufferedImage pbOut = new BufferedImage(iW, iOutH,
				BufferedImage.TYPE_INT_RGB);

		for (int y = 0; y < iOutH; y++) {

			int startY;
			int start;
			int Y = (int) (((double) y) * ((double) iH) / ((double) iOutH) + 0.5);

			startY = Y - nHalfDots;
			if (startY < 0) {
				startY = 0;
				start = nHalfDots - Y;
			} else {
				start = 0;
			}

			int stop;
			int stopY = Y + nHalfDots;
			if (stopY > (int) (iH - 1)) {
				stopY = iH - 1;
				stop = nHalfDots + (iH - 1 - Y);
			} else {
				stop = nHalfDots * 2;
			}

			if (start > 0 || stop < nDots - 1) {
				CalTempContrib(start, stop);
				for (int x = 0; x < iW; x++) {
					value = VerticalFilter(pbImage, startY, stopY, start, stop,
							x, tmpContrib);
					pbOut.setRGB(x, y, value);
				}
			} else {
				for (int x = 0; x < iW; x++) {
					value = VerticalFilter(pbImage, startY, stopY, start, stop,
							x, normContrib);
					pbOut.setRGB(x, y, value);
				}
			}

		}

		return pbOut;

	} // end of VerticalFiltering()

	private int Clip(int x) {
		if (x < 0)
			return 0;
		if (x > 255)
			return 255;
		return x;
	}

	/**
	 * End: Use Lanczos filter to replace the original algorithm for image
	 * scaling. Lanczos improves quality of the scaled image modify by :blade
	 */

}
  • pic.rar (2.6 KB)
  • 描述: 源代码和测试代码
  • 下载次数: 382
0 请登录后投票
   发表时间:2007-12-25  
lszone 写道
用ImageMagick不好吗?这么麻烦

没有用过这个软件,看了下介绍还蛮好的,就是要安装,麻烦,大家可以试一试,看看下面一片文章
http://blog.donews.com/baggio785/archive/2005/12/28/674624.aspx
内容如下:
ImageMagick一个优秀的图像处理软件,JMagick是对ImageMagickJAVA面向对象化包装。

现在谈谈如何在WINDOWS环境下、LINUX环境下这两款软件的安装与使用。并制作了一个缩略图的产生程序。

1、安装
在WINDOWS下安装及使用都相当简单。先去下载IImageMagic WINDOWS的安装包,安装一把就可以了。安装完结之后,一般都把DLL加入到类路径中去了。安装最新版的就可以了(6.0.4版)

安装JMagick,直接得到它的二进制包就可以了(5.6.0)版。将JAR文件放到JAVA类路径下面,将DLL文件放到SYSTEM32目录下,就OK了。


在UNIX环境下安装比较麻烦。
偶这里是用TAR包安装的。先去下载,这里都使用5。6。0版本。
先安装ImageMagick
过程:
  解开包文件
  ./configure 配置文件
  make all
  make install
  就OK了。当然你在配置文件的时候,可以控制一些配置。以保证安装成功。

对JMagick也是同样操作。
  解开包文件
  ./configure 配置文件
  make all
  make install
  make test
一般测试通过就OK了。

生成的静态类库或动态类库一般位于/usr/local/lib目录下。

如果需要在程序中使用,需要输出LD_LIBRARY_PATH目录。就不多说了。

2、使用
    private boolean genearateSumImg(String orgImg) {
        boolean result = false;
 
        //取得原文件
        try {           
           
            MagickImage image = new MagickImage( new ImageInfo( orgImg ) );
            int    scalex = 80;
            int    scaley = 80;                        
            MagickImage small =  image.scaleImage( scalex,scaley);
            small.setFileName( orgImg+IMAGE_SUM_POSTFIX);
            small.writeImage( new ImageInfo() );
 
            result = true;
        } catch (Exception e1) {
            e1.printStackTrace();
        }
        return result;
    }

以上是一个简单的生成缩略图的函数,可以EJB等处使用。

3、可能存在的问题及解决办法
在WEBLOGIC或者TOMCAT中使用。JMagick缺少是采用系统类加载器加载的,当然你也可以修改这个类加载器。

System.setProperty("jmagick.systemclassloader","no");
如采用如上的方法。
参考http://www.yeo.id.au/jmagick/ ,要在tomcat中使用JMagicK需要这三步:
1. Put Jmagick.jar in your WEBINF/lib dir
2. Put the following line in an initialization part of your webapp:
//Tell jmagick.magick.Magick to not use the system ClassLoader
System.setProperty("jmagick.systemclassloader","no");
3. make sure the Jmagick.dll and Imagemagick dlls are on the system
path
以上3步缺一不可

java.lang.UnsatisfiedLinkError: no JMagick in java.library.path
一般是没有输出库文件路径造成的。

NoDecodeDelegateForThisImageFormat: NoDecodeDelegateForThisImageFormat
一般是LINUX中没有安装一些SO文件造成的,可去下载来,在配置能看到输出的情况的,回答YES这个格式也就支持了。
0 请登录后投票
   发表时间:2008-02-17  
aumy2008 写道
如果是在上传前生成缩略图 ,就不用那么麻烦,直接用js就行了。

请教如何实现...

生成多张缩略尺寸又如何解决...
0 请登录后投票
   发表时间:2008-02-18  
用js生成缩略图,没有听说过,还是应该在服务器上生成,毕竟图片的生成,计算还是比较复杂的
0 请登录后投票
   发表时间:2008-02-18  
目前java处理图片还没有一个说的上好用的解决方案的.

java本身的这种api处理图片,当压缩到尺寸比较小时,会有明显的模糊及锯齿效果,极其恶心.

一种可选的方案是使用imagemagick.不过这是个软件,需要安装的.用java的jni来本地调用.有个叫jmagick的项目.也需要安装.并且两个东西安装极其困难,主要是版本的匹配.在官网找不到历史版本.

image magick + jmagick  可以说是从图片处理效果上来说最棒的java的方案了.jni本地调用人家的专业软件嘛.注意,仅仅是从效果上说.
不过jmagick这个项目委实叫人不敢恭维.
0 请登录后投票
   发表时间:2008-02-18  
weifly 写道
用js生成缩略图,没有听说过,还是应该在服务器上生成,毕竟图片的生成,计算还是比较复杂的


用js来生成缩略图是可以,但是前提是你必须已经有image这个js对象,然后再new一个Image,按照比例进行缩放,是可以生成图片的;但是这种解决办法的问题是原来大的图片仍然需要取得,那还要生成缩略图干嘛呢,直接调节图片的大小就可以了嘛;
0 请登录后投票
   发表时间:2008-02-27  
yyjn12 写道
目前java处理图片还没有一个说的上好用的解决方案的.

java本身的这种api处理图片,当压缩到尺寸比较小时,会有明显的模糊及锯齿效果,极其恶心.

一种可选的方案是使用imagemagick.不过这是个软件,需要安装的.用java的jni来本地调用.有个叫jmagick的项目.也需要安装.并且两个东西安装极其困难,主要是版本的匹配.在官网找不到历史版本.

image magick + jmagick  可以说是从图片处理效果上来说最棒的java的方案了.jni本地调用人家的专业软件嘛.注意,仅仅是从效果上说.
不过jmagick这个项目委实叫人不敢恭维.

不用jmagick,直接用JAVA生成命令行执行处理
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics