项目需要调整图片服务器的解决方案,这次调整使用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);
}
}
我大功告成了!
分享到:
相关推荐
Java 图片处理解决方案:ImageMagick 快速入门教程 Java 图片处理解决方案中,ImageMagick 是一个免费的创建、编辑、合成图片的软件,可以实现图片切割、颜色替换、图片缩略图、图片水印等各种效果。ImageMagick 是...
总的来说,`camera.swf`是一个全面的Java图片处理解决方案,集成了图片上传、等比缩放、截取和多尺寸生成功能。它利用了Java强大的图像处理能力,同时也考虑到了前端用户体验,通过SWFUpload提供了友好的上传界面。...
在Java编程领域,图片处理是一项常见的任务,包括添加水印、改变图片大小等。这里我们将深入探讨这些知识点,以及如何在Struts2框架下实现它们。 首先,让我们了解"图片水印"。水印通常用于保护版权或者为图片增加...
本文将深入探讨如何在Java中有效处理这些方面的问题,特别是超时处理解决方案,这对于构建高效、稳定的网络应用至关重要。 ### Java访问网络 在Java中,访问网络通常涉及到使用`java.net`包中的类,如`URL`和`...
【Java高并发解决方案】 在构建大型网站,尤其是门户网站时,面临的主要挑战之一是处理大量用户访问和高并发请求。为了应对这一挑战,通常会采取一系列技术措施,包括使用高性能服务器、数据库、编程语言以及Web...
### JAVA-OCR图文识别解决方案分析 #### 方案一:个人申请 **优点:** - **识别准确率高:**此方案提供了高度精确的文字识别能力,适用于对准确性有较高要求的应用场景。 - **处理速度快:**相比其他方案,该方案...
使用 Java Filter 来实现防盗链的解决方案。 ```java public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest...
"Java将图片组合成PDF文件的方法" ...Java将图片组合成PDF文件的方法是一种实用的解决方案,可以快速地将图片组合成PDF文件,提高工作效率。但是,需要学习iText库和图形用户界面编程,增加了学习成本和编程难度。
总的来说,Java的Jimi包提供了一套完整的图像处理解决方案,包括图像加载、格式转换和保存等功能。通过熟练掌握这些API,开发者可以轻松地在Java应用程序中实现图片格式的转换,无论是简单的单张图片操作,还是复杂...
总的来说,这个项目结合了前端的Jquery技术与后端的Java能力,为用户提供了一套完整的图片处理解决方案,涵盖了图片选择、切割、滤镜应用以及服务器端的存储和处理。这种技术组合在Web开发中非常常见,对于理解前后...
在数据库集群方面,很多数据库都有自己的解决方案,Oracle、Sybase等都有很好的方案,常用的MySQL提供的Master/Slave也是类似的方案,您使用了什么样的DB,就参考相应的解决方案来实施即可。 上面提到的数据库集群...
"Java中Excel转图片工具包(纯java)"就是这样一个解决方案,它实现了将Excel文件通过PDF中间格式转化为图片的功能。 首先,让我们了解一下这个工具包的工作原理。Excel文件本身并不直接支持转换为图片格式,但可以...
在Java编程领域,将文字转换为图片...这将有助于实现更灵活的解决方案。 总之,Java中的文字转图片功能通过结合`Graphics2D`、`BufferedImage`、`Font`等类,可以实现各种定制化的文本图像生成,满足不同的应用场景。
本资源提供了Java和Python两种语言的解决方案,旨在帮助开发者理解和实现验证码识别。以下是对这两种语言中验证码识别技术的详细解释。 ### Python验证码识别 Python在图像处理和机器学习领域有着丰富的库支持,...
9. **多平台兼容性**:Java的跨平台特性使得PDF转图片的解决方案可以在Windows、Linux和Mac OS等多种操作系统上运行。 10. **实战示例**:下面是一个使用Apache PDFBox进行PDF转图片的简单代码示例: ```java ...
这个课程设计项目旨在提供一个全面的解决方案,帮助用户轻松地浏览、预览、删除以及复制图片,提升了用户在日常图片处理中的效率。 首先,我们要理解Java在图片处理中的核心概念。Java提供了丰富的API来处理图像,...
总之,这个项目提供了一个全面的图像处理解决方案,涵盖了从基本的图像操作到高级的图像处理技术,并确保了代码的质量和功能的完整性。无论是开发者想要学习Java图像处理,还是需要在实际项目中应用这些功能,这个...
本项目“java图片上传.zip”显然提供了一个实现图片上传到本地服务器和图片服务器的解决方案。以下将详细讲解这一过程涉及的关键知识点,以及如何在实际开发中应用这些技术。 1. **MultipartFile接口**: Java ...
session跨域共享及企业级单点登录解决方案实战 分布式事务解决方案实战 高并发下的服务降级、限流实战 基于分布式架构下分布式锁的解决方案实战 分布式架构实现分布式定时调度 分布式架构-中间件 分布式消息...