`
zkl_1987
  • 浏览: 242210 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

java图片处理解决方案

阅读更多
项目需要调整图片服务器的解决方案,这次调整使用fastdfs存储小文件,也就是图片,因为现在还没有fastdfs的.net版的客服端,所以理所当然把处理图片放到了java这块,使用java来处理图片并且上传到fastdfs上。

之前还真没用java整过图片,因为一般没这个需求,现在的需求是要根据前台传过来的尺寸进行图片的缩略,自适应缩放,留白,加水印操作。

一开始我使用jdk自带的一套图片处理库来处理图片,也就是sun的JPEGCodec,测试发现它会把所有的图片全部转换成jpeg格式,也就是说把bmp,gif,png这种格式的图片全部转换成了jpeg格式,而且对于gif动画图片缩放就只能对第一帧缩放,所以对于gif这种的的缩放完之后就“不动了”。

之后使用Graphics2D+ImageIO的方式,先判断图片的格式,然后缩放的时候强制的把图片格式作为参数传给ImageIO来处理,
ImageIO.write(image, pic_type, out);


但是对于gif动画图片缩放也只对第一帧缩放,所以对于gif这种的的缩放完之后也是“不动了”。
最后在网上发现了一个架包 --gif4j ,它可以对gif动画图片进行缩放但是对于加水印和留白操作就无能为力了。

最后在做压力测试时发现,使用这种方式(java的jdk+gif4j),特别是对于大图的操作,大图我这边测试的是6~7M的图片,发现非常非常耗cpu和内存,当然程序已经优化过的前提下测试,图片都以流的方式进行操作。但是这种cpu和内存的消耗简直是开玩笑了,要是需要处理的图片一多,每秒过百的请求服务器就得卡死,而且这种方式处理的图片质量不是特别高。


在这种方案放弃之后,发现了ImageMagick。
ImageMagick (TM) 是一个免费的创建、编辑、合成图片的软件。它可以读取、转换、写入多种格式的图片。图片切割、颜色替换、各种效果的应用,图片的旋转、组合,文本,直线,多边形,椭圆,曲线,附加到图片伸展旋转。ImageMagick的大多数功能的使用都来源于命令行工具。它还支持以下程序语言: Perl, C, C++, Python, PHP, Ruby, Java;现成的ImageMagick接口(PerlMagick, Magick++, PythonMagick, MagickWand for PHP, RubyMagick, and JMagick)是可利用的。


利用Java 的JNI(java本地调用),依赖操作系统提供的功能, 操作批量、大图片,这种方式效率比较高。
然后当然是开搞,ImageMagick 在windows和linux下的配置稍有不同,详细情况可以参考:http://www.imagemagick.org/script/index.php


下面贴出使用JMagick调用Imagemagick进行缩略的代码。


public void resize1(String src, String dsec, int width, int height,
			int quality) {
		ImageInfo info = null;
		MagickImage image = null;
		Dimension imageDim = null;
		MagickImage scaled = null;
		try {
			info = new ImageInfo(src);
			info.setQuality(quality);
			image = new MagickImage(info);
			imageDim = image.getDimension();

			int srcW = imageDim.width;
			int srcH = imageDim.height;
			
			int[] i = PicUtil.getWandH(srcW, srcH, width, height, 1);

			scaled = image.scaleImage(i[0], i[1]);
			scaled.setFileName(dsec);
			scaled.writeImage(info);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (scaled != null) {
				scaled.destroyImages();
			}
			if (image != null) {
				image.destroyImages();
			}
		}
	}



这里注意,使用完之后要释放资源。

if (scaled != null) {
				scaled.destroyImages();
			}
			if (image != null) {
				image.destroyImages();
			}


否则会很伤,你懂的。



加水印代码:
	public void addWater(String src, String src_biao, String dsrc,
			int position, int quality) {
		ImageInfo info = null;
		ImageInfo logo_info = null;
		MagickImage image = null;
		MagickImage logo_image = null;
		Dimension imageDim = null;
		Dimension logo_imageDim = null;
		// MagickImage compositeimage = null;
		try {
			info = new ImageInfo(src);
			info.setQuality(quality);
			image = new MagickImage(info);
			imageDim = image.getDimension();
			logo_info = new ImageInfo(src_biao);
			logo_image = new MagickImage(logo_info);
			logo_imageDim = logo_image.getDimension();

			int[] ii = WaterPosition.position(position, imageDim.width,
					logo_imageDim.width, imageDim.height, logo_imageDim.height);
			image.compositeImage(CompositeOperator.AtopCompositeOp, logo_image,
					ii[0], ii[1]);
			image.setFileName(dsrc);
			image.writeImage(info);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (logo_image != null) {
				logo_image.destroyImages();
			}
			if (image != null) {
				image.destroyImages();
			}
		}
	}




代码都整完之后,进行压力测试,问题出来了,java调用JNI的方式存在内存隐患,至于原因,可以网上查查。现在的情况就是如果可以10天半个月重启下服务,那没问题,但是如果长时间的跑着服务,它会把内存耗尽,然后死掉。

很郁闷,是吧,我也很郁闷。但我想做就做个NB点的吧,然后发现了GraphicsMagick+im4java这种方式。
具体的不介绍了,网上资料很少,例子代码更少,我在这里贴几段,仅供参考。



缩放代码:
	public void resize1(String src, String dsec, int o_width, int o_heigh,
			int width, int height, double quality) {
		int[] i = PicUtil.getWandH(o_width, o_heigh, width, height, 1);
		ConvertCmd cmd = new ConvertCmd(true);
		IMOperation op = new IMOperation();
		op.addImage(src);
		op.scale(i[0], i[1]);
		op.quality(quality);
		op.addImage(dsec);
		try {
			cmd.run(op);
		} catch (Exception e) {
			log.error(e,e);
		}
	}





加水印:

	public void addWater(String src, String src_biao, String dsrc,
			int position, double quality) {
		CompositeCmd cmd = new CompositeCmd(true);
		IMOperation op = new IMOperation();
		op.gravity(WaterPosition.positionMagick(position));
		op.quality(quality);
		op.addImage();
		op.addImage();
		op.addImage();
		try {
			cmd.run(op, src_biao, src, dsrc);
		} catch (Exception e) {
			log.error(e,e);
		}
	}


我大功告成了!
2
5
分享到:
评论
2 楼 你的样子越来越美 2017-03-01  
楼主是来炫耀的。
1 楼 andylo25 2011-06-08  
“具体的不介绍了,网上资料很少,例子代码更少”
不知道这个是什么意思?
是因为资料少,物以稀为贵,表示你很NB,所以不介绍呢?还是写错了?

相关推荐

    Java图片处理解决方案:ImageMagick快速入门教程.docx

    Java图片处理解决方案:ImageMagick快速入门教程.docx

    java 访问网络 下载文件 爬虫 超时处理解决方案

    java 访问网络 下载文件 爬虫 超时处理解决方案

    Java思维导图xmind文件+导出图片

    session跨域共享及企业级单点登录解决方案实战 分布式事务解决方案实战 高并发下的服务降级、限流实战 基于分布式架构下分布式锁的解决方案实战 分布式架构实现分布式定时调度 分布式架构-中间件 分布式消息...

    Jmagick缩图 JAVA图片处理

    开发图片搜索系统时用到的图片缩图解决方案,里面带了例子

    图片过大引起的内存溢出解决方案

    使用BitmapFactory加载图片时,如果图片过大可能引起OutOfmemory溢出的问题。解决办法。

    java图形图象处理系统设计与实现源码

    该系统的目标是为上述人群提供一个方便、快捷、高效的图像处理解决方案,并打造一个开放、自由、易用、性能稳定的图像处理平台。 使用本系统需要掌握一定的计算机基础知识和图形图像处理的基础知识,同时需要注重...

    java开源包5

    JSTUN 是另外一个用来解决穿越 NAT 进行通讯的 Java 解决方案,是 STUN 协议的 Java实现。 在浏览器上运行Java程序 Doppio DoppioVM 是一个可在浏览器上直接运行 Java 项目的系统,无需任何插件支持。目前它包含一...

    java pdf方案测试

    java html生成pdf的解决方案,包括常见错误的处理,如中文问题、css路径、图片,内有测试例子等。是java中pdf方案的好帮手哦

    JAVA上百实例源码以及开源项目

     util实现Java图片水印添加功能,有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明度、水印旋转等,可以参考代码...

    JAVA上百实例源码以及开源项目源代码

     util实现Java图片水印添加功能,有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明度、水印旋转等,可以参考代码...

    java开源包11

    JSTUN 是另外一个用来解决穿越 NAT 进行通讯的 Java 解决方案,是 STUN 协议的 Java实现。 在浏览器上运行Java程序 Doppio DoppioVM 是一个可在浏览器上直接运行 Java 项目的系统,无需任何插件支持。目前它包含一...

    java开源包6

    JSTUN 是另外一个用来解决穿越 NAT 进行通讯的 Java 解决方案,是 STUN 协议的 Java实现。 在浏览器上运行Java程序 Doppio DoppioVM 是一个可在浏览器上直接运行 Java 项目的系统,无需任何插件支持。目前它包含一...

    java开源包9

    JSTUN 是另外一个用来解决穿越 NAT 进行通讯的 Java 解决方案,是 STUN 协议的 Java实现。 在浏览器上运行Java程序 Doppio DoppioVM 是一个可在浏览器上直接运行 Java 项目的系统,无需任何插件支持。目前它包含一...

    java开源包101

    JSTUN 是另外一个用来解决穿越 NAT 进行通讯的 Java 解决方案,是 STUN 协议的 Java实现。 在浏览器上运行Java程序 Doppio DoppioVM 是一个可在浏览器上直接运行 Java 项目的系统,无需任何插件支持。目前它包含一...

    java开源包4

    JSTUN 是另外一个用来解决穿越 NAT 进行通讯的 Java 解决方案,是 STUN 协议的 Java实现。 在浏览器上运行Java程序 Doppio DoppioVM 是一个可在浏览器上直接运行 Java 项目的系统,无需任何插件支持。目前它包含一...

    java开源包8

    JSTUN 是另外一个用来解决穿越 NAT 进行通讯的 Java 解决方案,是 STUN 协议的 Java实现。 在浏览器上运行Java程序 Doppio DoppioVM 是一个可在浏览器上直接运行 Java 项目的系统,无需任何插件支持。目前它包含一...

    java开源包10

    JSTUN 是另外一个用来解决穿越 NAT 进行通讯的 Java 解决方案,是 STUN 协议的 Java实现。 在浏览器上运行Java程序 Doppio DoppioVM 是一个可在浏览器上直接运行 Java 项目的系统,无需任何插件支持。目前它包含一...

    java开源包3

    JSTUN 是另外一个用来解决穿越 NAT 进行通讯的 Java 解决方案,是 STUN 协议的 Java实现。 在浏览器上运行Java程序 Doppio DoppioVM 是一个可在浏览器上直接运行 Java 项目的系统,无需任何插件支持。目前它包含一...

    java开源包1

    JSTUN 是另外一个用来解决穿越 NAT 进行通讯的 Java 解决方案,是 STUN 协议的 Java实现。 在浏览器上运行Java程序 Doppio DoppioVM 是一个可在浏览器上直接运行 Java 项目的系统,无需任何插件支持。目前它包含一...

    JAVA基础课程讲义

    死锁及解决方案 179 生产者/消费者模式 181 线程回顾总结 184 任务调度(补充内容,了解即可!) 184 思考作业 185 上机作业 185 第十章 网络编程 186 基本概念 186 什么是计算机网络 186 计算机网络的主要功能 186 ...

Global site tag (gtag.js) - Google Analytics