热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

IM4Java+GraphicsMagick实现高清图片剪裁处理

2019独角兽企业重金招聘Python工程师标准简单介绍GraphicsMagick是ImageMagick的一个分支,相对于ImageMagick而言

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

简单介绍

GraphicsMagick是ImageMagick的一个分支,相对于ImageMagick而言,TA处理速度更快,消耗资源更少。GraphicsMagick 是一个用来读写、生成超过90种图像格式的工具集合,支持包括 TIFF, JPEG, JPEG-2000,PNG, PDF, PhotoCD, SVG, 和GIF 等图像格式。GraphicsMagick 是基于 ImageMagick 开发的。

im4java是ImageMagick的另一个Java开源接口。与JMagick不同之处在于im4java只是生成与ImageMagick相对应的命令行,然后将生成的命令行传至选中的IM-command(使用java.lang.ProcessBuilder.start()实现)来执行相应的操作。它支持大部分ImageMagick命令,可以针对不同组的图片多次复用同一个命令行。im4java也是能够高清压缩图片,而且它也特别强大,至少一些基本常见的业务都是可以完美实现的。

Cropper是一款使用简单且功能强大的图片剪裁jQuery插件。该图片剪裁插件支持图片放大缩小,支持鼠标滚轮操作,支持图片旋转,支持触摸屏设备,支持canvas,并且支持跨浏览器使用。

技术选型

ImageCropper + GraphicsMagick + im4java + SpringMVC

ImageCropper官网: http://fengyuanchen.github.io/cropper/
GraphicsMagick官网: http://www.graphicsmagick.org/
im4java下载: http://sourceforge.net/projects/im4java/files/?source=navbar

处理逻辑
    1、前端进行图片剪裁,并展示剪裁后的效果图;
    2、点击确定后,将参数(x,y坐标,长宽,旋转角度)传到后端,并将图片上传至服务器,在调用im4java api进行图片处理。
    3、返回处理后的图片路径,前端展示。
 

编程实现

图片剪裁处理类

package org.hcm.utils;import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.im4java.core.ConvertCmd;
import org.im4java.core.IM4JavaException;
import org.im4java.core.IMOperation;import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;public class ImageUtils {private static Log logger &#61; LogFactory.getLog(ImageUtils.class);/*** 保存文件** &#64;param inputStream* &#64;param path* &#64;param fileName*/public static void saveFileFromInputStream(InputStream inputStream, String path, String fileName) {File file &#61; new File(path &#43; fileName);FileOutputStream fs &#61; null;try {fs &#61; new FileOutputStream(file);byte[] buffer &#61; new byte[1024 * 1024];int byteread &#61; 0;while ((byteread &#61; inputStream.read(buffer)) !&#61; -1) {fs.write(buffer, 0, byteread);fs.flush();}} catch (FileNotFoundException e) {logger.error("File Not Found !", e);} catch (IOException e) {logger.error("", e);} finally {try {if (fs !&#61; null) {fs.close();}if (inputStream !&#61; null) {inputStream.close();}} catch (IOException e) {logger.error("", e);}}}/*** 裁剪图片* * &#64;param imagePath* 源图片路径* &#64;param newPath* 处理后图片路径* &#64;param x* 起始X坐标* &#64;param y* 起始Y坐标* &#64;param width* 裁剪宽度* &#64;param height* 裁剪高度* &#64;return 返回true说明裁剪成功,否则失败*/public static boolean cutImage(String imagePath, String newPath, int x, int y, int width, int height) {boolean flag &#61; false;try {IMOperation op &#61; new IMOperation();op.addImage(imagePath);/** width&#xff1a;裁剪的宽度 * height&#xff1a;裁剪的高度 * x&#xff1a;裁剪的横坐标 * y&#xff1a;裁剪纵坐标 */op.crop(width, height, x, y);op.addImage(newPath);ConvertCmd convert &#61; new ConvertCmd(true);convert.run(op);flag &#61; true;} catch (IOException e) {logger.error("读取文件出错", e);} catch (InterruptedException e) {logger.error("", e);} catch (IM4JavaException e) {logger.error("", e);}return flag;}/*** 根据尺寸缩放图片[等比例缩放:参数height为null,按宽度缩放比例缩放;参数width为null,按高度缩放比例缩放]* * &#64;param imagePath* 源图片路径* &#64;param newPath* 处理后图片路径* &#64;param width* 缩放后的图片宽度* &#64;param height* 缩放后的图片高度* &#64;return 返回true说明缩放成功,否则失败*/public static boolean zoomImage(String imagePath, String newPath, Integer width, Integer height) {boolean flag &#61; false;try {IMOperation op &#61; new IMOperation();op.addImage(imagePath);if (width &#61;&#61; null) { // 根据高度缩放图片op.resize(null, height);} else if (height &#61;&#61; null) { // 根据宽度缩放图片op.resize(width);} else {op.resize(width, height);}op.addImage(newPath);ConvertCmd convert &#61; new ConvertCmd(true);convert.run(op);flag &#61; true;} catch (IOException e) {logger.error("读取文件出错", e);} catch (InterruptedException e) {logger.error("", e);} catch (IM4JavaException e) {logger.error("", e);} return flag;}/*** 图片旋转* * &#64;param imagePath* 源图片路径* &#64;param newPath* 处理后图片路径* &#64;param degree* 旋转角度*/public static boolean rotate(String imagePath, String newPath, double degree) {boolean flag &#61; false;try {// 1.将角度转换到0-360度之间degree &#61; degree % 360;if (degree <&#61; 0) {degree &#61; 360 &#43; degree;}IMOperation op &#61; new IMOperation();op.addImage(imagePath);op.rotate(degree);op.addImage(newPath);ConvertCmd cmd &#61; new ConvertCmd(true);cmd.run(op);flag &#61; true;} catch (Exception e) {logger.error("图片旋转处理失败!", e);}return flag;}public static boolean imgProcessing(String srcPath, String destPath, int x, int y, int width, int height, double rotate) {boolean flag &#61; false;try {IMOperation op &#61; new IMOperation();op.addImage(srcPath);/** 旋转 */op.rotate(rotate);/** width&#xff1a;裁剪的宽度 * height&#xff1a;裁剪的高度 * x&#xff1a;裁剪的横坐标 * y&#xff1a;裁剪纵坐标 */op.crop(width, height, x, y);op.addImage(destPath);ConvertCmd convert &#61; new ConvertCmd(true);convert.run(op);flag &#61; true;} catch (IOException e) {logger.error("读取文件出错", e);} catch (InterruptedException e) {logger.error("", e);} catch (IM4JavaException e) {logger.error("", e);}return flag;}public static void main(String[] args) {
// ImageUtils.zoomImage("f://temp//test.jpg", "f://temp//test5.jpg", 200, 200);
// ImageUtils.rotate("f://temp//test1.jpg", "f://temp//test2.jpg", -90);
// ImageUtils.cutImage("f://temp//test5.jpg", "f://temp//test5.jpg", 32, 30, 200, 200);String data &#61; "{&#39;x&#39;:100.001, &#39;y&#39;:100.9}";System.out.println(data);JSONObject jsonData &#61; JSON.parseObject(data);System.out.println(jsonData.getIntValue("x"));System.out.println(jsonData.getIntValue("y"));}}


控制类

package org.hcm.controller;import java.io.IOException;
import java.util.HashMap;
import java.util.Map;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import org.apache.commons.lang.StringUtils;
import org.hcm.utils.ImageUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;&#64;Controller
&#64;RequestMapping(value &#61; "/image")
public class ImageController {&#64;RequestMapping(value &#61; "/upload", method &#61; RequestMethod.POST)public void upload(HttpServletRequest req, HttpServletResponse resp) throws IOException {Map result &#61; new HashMap();MultipartHttpServletRequest multipartRequest &#61; (MultipartHttpServletRequest) req;MultipartFile file &#61; multipartRequest.getFile("avatar_file");String data &#61; req.getParameter("avatar_data");String fileName &#61; String.valueOf(System.currentTimeMillis()) &#43; getExtension(file.getOriginalFilename());String savePath &#61; req.getServletContext().getRealPath("/upload");if (!file.isEmpty()) {// 保存原图ImageUtils.saveFileFromInputStream(file.getInputStream(), savePath &#43; "\\source\\", fileName);// 处理图片result &#61; imageProcessing(data, savePath, fileName, req.getContextPath()); } resp.getWriter().print(JSON.toJSON(result));}private Map imageProcessing(String data, String savePath, String fileName, String contextPath) {Map map &#61; new HashMap();JSONObject object &#61; JSONObject.parseObject(data);int x &#61; (int) object.getIntValue("x");int y &#61; object.getIntValue("y");int height &#61; object.getIntValue("height");int width &#61; object.getIntValue("width");int rotate &#61; object.getIntValue("rotate");String srcPath &#61; savePath &#43; "\\source\\" &#43; fileName;String destPath &#61; savePath &#43; "\\procesed\\" &#43; fileName;String serverPath &#61; contextPath &#43; "/upload/procesed/" &#43; fileName;ImageUtils.imgProcessing(srcPath, destPath, x, y, width, height, rotate);map.put("state", 200);map.put("result", serverPath);return map;}private String getExtension(String fileName) {if (StringUtils.INDEX_NOT_FOUND &#61;&#61; StringUtils.indexOf(fileName, "."))return StringUtils.EMPTY;String ext &#61; StringUtils.substring(fileName, StringUtils.lastIndexOf(fileName, "."));return StringUtils.trimToEmpty(ext);} }


效果预览




&#xff08;完&#xff09;


转载于:https://my.oschina.net/huangcongmin12/blog/649413


推荐阅读
  • 本文介绍了OkHttp3的基本使用和特性,包括支持HTTP/2、连接池、GZIP压缩、缓存等功能。同时还提到了OkHttp3的适用平台和源码阅读计划。文章还介绍了OkHttp3的请求/响应API的设计和使用方式,包括阻塞式的同步请求和带回调的异步请求。 ... [详细]
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 本文记录了在vue cli 3.x中移除console的一些采坑经验,通过使用uglifyjs-webpack-plugin插件,在vue.config.js中进行相关配置,包括设置minimizer、UglifyJsPlugin和compress等参数,最终成功移除了console。同时,还包括了一些可能出现的报错情况和解决方法。 ... [详细]
  • Android实战——jsoup实现网络爬虫,糗事百科项目的起步
    本文介绍了Android实战中使用jsoup实现网络爬虫的方法,以糗事百科项目为例。对于初学者来说,数据源的缺乏是做项目的最大烦恼之一。本文讲述了如何使用网络爬虫获取数据,并以糗事百科作为练手项目。同时,提到了使用jsoup需要结合前端基础知识,以及如果学过JS的话可以更轻松地使用该框架。 ... [详细]
  • 从零基础到精通的前台学习路线
    随着互联网的发展,前台开发工程师成为市场上非常抢手的人才。本文介绍了从零基础到精通前台开发的学习路线,包括学习HTML、CSS、JavaScript等基础知识和常用工具的使用。通过循序渐进的学习,可以掌握前台开发的基本技能,并有能力找到一份月薪8000以上的工作。 ... [详细]
  • Commit1ced2a7433ea8937a1b260ea65d708f32ca7c95eintroduceda+Clonetraitboundtom ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • 本文讨论了在手机移动端如何使用HTML5和JavaScript实现视频上传并压缩视频质量,或者降低手机摄像头拍摄质量的问题。作者指出HTML5和JavaScript无法直接压缩视频,只能通过将视频传送到服务器端由后端进行压缩。对于控制相机拍摄质量,只有使用JAVA编写Android客户端才能实现压缩。此外,作者还解释了在交作业时使用zip格式压缩包导致CSS文件和图片音乐丢失的原因,并提供了解决方法。最后,作者还介绍了一个用于处理图片的类,可以实现图片剪裁处理和生成缩略图的功能。 ... [详细]
  • 解决文件名过长下载失败问题的jQuery方案
    本文介绍了使用jQuery解决文件名过长导致下载失败的问题。原方案中存在文件名部分丢失的问题,通过动态生成隐藏域表单并提交的方式来解决。详细的解决方案和代码示例在文章中给出。 ... [详细]
  • 本文介绍了Android中的assets目录和raw目录的共同点和区别,包括获取资源的方法、目录结构的限制以及列出资源的能力。同时,还解释了raw目录中资源文件生成的ID,并说明了这些目录的使用方法。 ... [详细]
  • 如何压缩网站页面以减少页面加载时间
    本文介绍了影响网站打开时间的两个因素,即网页加载速度和网站页面大小。重点讲解了如何通过压缩网站页面来减少页面加载时间。具体包括图片压缩、Javascript压缩、CSS压缩和HTML压缩等方法,并推荐了相应的压缩工具。此外,还提到了一款Google Chrome插件——网页加载速度分析工具Speed Tracer。 ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了css回到顶部按钮相关的知识,希望对你有一定的参考价值。 ... [详细]
  • higuysihaveproblemwithtreeshakinginnx,problemwithassetslibrary ... [详细]
  • 今天周六,原则上要休息,但想到下周还有一堆任务,还是先做一部分工作吧,就把之前做的票面设计器改了改,增加了上传图片和更换背景底图的功能。现在打算整理下这个设计器,也算对齐一个总结。不过这属于我们部门的 ... [详细]
author-avatar
Fxnananana
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有