项目描述

imagemagick是功能强大的图片处理库,以稳定及高效率著称,众多语言对该库进行封装处理。比如php、java。由于我们是java项目,直接使用java通过JNI技术调用ImageMagick是不行的。因为ImageMagick开发时没有使用java JNI生成的头文件。可以使用JMagick解决,JMagick是由c语言开发的,开发时使用了java JNI生成的头文件,所以java可以通过JNI技术调用JMagick。JMagick再调用ImageMagick。这里我们处理图片使用的是JMagick暴露的java接口。

下载和安装

Windows安装使用Jmagick及imagemagick步骤如下:

1、访问jmagick网站下载: http://downloads.jmagick.org

2、目前JMagick只有32位的,所以只能选择32位的ImageMagick,并且版本支持很低,目前只到ImageMagick-6.3.9-0,只能使用32位的JDK,64位进程不能够调用32位的dll,想在64位的系统上用jmagick不仅要将jdk换成32位,而且jmagick.dll也得放到SysWOW64下面,不能放到System32中。

3、下载两个文件:红框的两个或者绿框的两个。

关于Q8,Q16,Q32的说明:(建议使用8,现在数码相机照的相片,每一种颜色就是8位深,3种颜色就是24位,所以选8) 
支持的参数有3种,分别是 8,16,32。默认值是16。 
Q8表示: 8-bits per pixel quantum 
Q16表示:16-bits per pixel quantum 
Q32表示:32-bits per pixel quantum

使用16-bit per pixel quantums在处理图片时比8-bit慢15%至50%,并须要更多的内存。 
处理一张1024x768像素的图片8-bit要使用3.6M内存,16-bit要使用7.2M内存。计算方法是: (5 * Quantum Depth * Rows * Columns) / 8

大多数电脑显示使用8-bit per pixel quantums。使用16-bit per pixel quantums在处理图片时比8-bit慢15%至50%,并须要更多的内存。比如处理一张1024x768像素的图片8-bit要使用3M内存,16-bit要使用8M内存。8-bit可表示0-255种值,16-bit可表示0-65535种值。默认值是8-bit。
另外Windows下有动态版(dll),有静态版(static),这里使用了动态版。

4、下载时注意版本问题。不要到imagemagick官方网站下载imagemagick,这样会导致下载的imagemagick版本和jmagick版本不对应,导致调用出现异常。比如出现memor allocate not enough 的异常。

这是我下载出来的文件(我公司电脑系统是WIN7-32位,安装的也是32位的JDK):

5、双击下载的ImageMagick-6.3.9-0-Q8-windows-dll.exe文件安装即可,一直点击下一步就可以。这里如果勾选了红框标注的选项,环境变量会自动配好的。

在命令行使用

到这里就可以在DOS命令窗口中使用了,具体使用命令可以参考这篇博客:http://www.charry.org/docs/linux/ImageMagick/ImageMagick.html,下面截图演示对桌面图片的处理:

在Java中使用

1、将ImageMagick安装目录下的所有的.dll文件复制到  C:/ windows/System32的目录下(这一步有可能省略,等待验证)

2、解压jmagick-win-6.3.9-Q8.zip , 将jmagick.dll放到 C:/windows/System32 目录下。这里是为了能在Java中使用jmagick的类进行操作ImageMagick,如果不复制的话,会报UnsatisfiedLinkError: no JMagick in java.library.path.异常。

3、将jmagick.jar加入到eclipse下相关项目的build path中的libraries  中即完成了相应的安装。接下来就可以在java项目中使用了。

4、Java中通过jmagick操作ImageMagick,示例代码:

 package com.demo.test;   

 import java.awt.Dimension;
import java.awt.Rectangle;
import java.text.SimpleDateFormat;
import java.util.Date; import magick.CompositeOperator;
import magick.CompressionType;
import magick.DrawInfo;
import magick.ImageInfo;
import magick.MagickException;
import magick.MagickImage;
import magick.PixelPacket;
import magick.PreviewType; public class ImageTools { static{
//不能漏掉这个,不然jmagick.jar的路径找不到
//System.setProperty("jmagick.systemclassloader","no");
} /**
* 压缩图片
* @param filePath 源文件路径
* @param toPath 缩略图路径
*/
public static void createThumbnail(String filePath, String toPath) throws MagickException{
ImageInfo info = null;
MagickImage image = null;
Dimension imageDim = null;
MagickImage scaled = null;
try{
info = new ImageInfo(filePath);
image = new MagickImage(info);
imageDim = image.getDimension();
int wideth = imageDim.width;
int height = imageDim.height;
if (wideth > height) {
height = 660 * height / wideth;
wideth = 660;
}
scaled = image.scaleImage(wideth, height);//小图片文件的大小.
scaled.setFileName(toPath);
scaled.writeImage(info);
}finally{
if(scaled != null){
scaled.destroyImages();
}
}
} /**
* 水印(图片logo)
* @param filePath 源文件路径
* @param toImg 修改图路径
* @param logoPath logo图路径
* @throws MagickException
*/
public static void initLogoImg(String filePath, String toImg, String logoPath) throws MagickException {
ImageInfo info = new ImageInfo();
MagickImage fImage = null;
MagickImage sImage = null;
MagickImage fLogo = null;
MagickImage sLogo = null;
Dimension imageDim = null;
Dimension logoDim = null;
try {
fImage = new MagickImage(new ImageInfo(filePath));
imageDim = fImage.getDimension();
int width = imageDim.width;
int height = imageDim.height;
if (width > 660) {
height = 660 * height / width;
width = 660;
}
sImage = fImage.scaleImage(width, height); fLogo = new MagickImage(new ImageInfo(logoPath));
logoDim = fLogo.getDimension();
int lw = width / 8;
int lh = logoDim.height * lw / logoDim.width;
sLogo = fLogo.scaleImage(lw, lh); sImage.compositeImage(CompositeOperator.AtopCompositeOp, sLogo, width-(lw + lh/10), height-(lh + lh/10));
sImage.setFileName(toImg);
sImage.writeImage(info);
} finally {
if(sImage != null){
sImage.destroyImages();
}
}
} /**
* 水印(文字)
* @param filePath 源文件路径
* @param toImg 修改图路径
* @param text 名字(文字内容自己随意)
* @throws MagickException
*/
public static void initTextToImg(String filePath, String toImg, String text) throws MagickException{
ImageInfo info = new ImageInfo(filePath);
if (filePath.toUpperCase().endsWith("JPG") || filePath.toUpperCase().endsWith("JPEG")) {
info.setCompression(CompressionType.JPEGCompression); //压缩类别为JPEG格式
info.setPreviewType(PreviewType.JPEGPreview); //预览格式为JPEG格式
info.setQuality(95);
}
MagickImage aImage = new MagickImage(info);
Dimension imageDim = aImage.getDimension();
int wideth = imageDim.width;
int height = imageDim.height;
if (wideth > 660) {
height = 660 * height / wideth;
wideth = 660;
}
int a = 0;
int b = 0;
String[] as = text.split("");
for (String string : as) {
if(string.matches("[\u4E00-\u9FA5]")){
a++;
}
if(string.matches("[a-zA-Z0-9]")){
b++;
}
}
int tl = a*12 + b*6 + 300;
MagickImage scaled = aImage.scaleImage(wideth, height);
if(wideth > tl && height > 5){
DrawInfo aInfo = new DrawInfo(info);
aInfo.setFill(PixelPacket.queryColorDatabase("white"));
aInfo.setUnderColor(new PixelPacket(0,0,0,100));
aInfo.setPointsize(12);
//解决中文乱码问题,自己可以去随意定义个自己喜欢字体,我在这用的微软雅黑
String fontPath = "C:/WINDOWS/Fonts/MSYH.TTF";
//String fontPath = "/usr/maindata/MSYH.TTF";
aInfo.setFont(fontPath);
aInfo.setTextAntialias(true);
aInfo.setOpacity(0);
aInfo.setText(" " + text + "于 " + new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + " 上传于我的相册网,版权归作者所有!");
aInfo.setGeometry("+" + (wideth-tl) + "+" + (height-5));
scaled.annotateImage(aInfo);
}
scaled.setFileName(toImg);
scaled.writeImage(info);
scaled.destroyImages();
} /**
* 切图
* @param imgPath 源图路径
* @param toPath 修改图路径
* @param w
* @param h
* @param x
* @param y
* @throws MagickException
*/
public static void cutImg(String imgPath, String toPath, int w, int h, int x, int y) throws MagickException {
ImageInfo infoS = null;
MagickImage image = null;
MagickImage cropped = null;
Rectangle rect = null;
try {
infoS = new ImageInfo(imgPath);
image = new MagickImage(infoS);
rect = new Rectangle(x, y, w, h);
cropped = image.cropImage(rect);
cropped.setFileName(toPath);
cropped.writeImage(infoS); } finally {
if (cropped != null) {
cropped.destroyImages();
}
}
} /**
* 测试
* @param args
*/
public static void main(String[] args) {
try {
cutImg("C:\\Users\\Administrator\\Desktop\\test\\new3.jpg", "C:\\Users\\Administrator\\Desktop\\test\\new5.jpg", 100, 100, 300, 150);
} catch (MagickException e) {
e.printStackTrace();
}
}
}

JMagic 操作 ImageMagick 处理图片的更多相关文章

  1. Im4java 操作 ImageMagick 处理图片

    背景 之前用的是JMagick,各种限制各种坑,直到使用了Im4java,真是相当的好用啊. 项目描述 ImageMagic的安装可参考:图片处理软件 ImageMagick 的安装和使用 Im4ja ...

  2. 使用ImageMagick处理图片后导致图片变大的问题

    最新在使用ImageMagick处理图片时,发现有时经过处理的图片变大的问题. 例如原图为27K,经处理后的图片会变为77K. 先看测试代码: // imgtest.cpp : 定义控制台应用程序的入 ...

  3. 使用gm和imageMagick处理图片

    第一步安装imageMagick和gm模块 1, cnpm install --save imageMagick gm 第二步在服务器上安装imageMagick,下载地址http://www.ima ...

  4. 图片处理服务 ImageMagick 的安装和使用

    简介 该文章使用目前官方最新版本7.0.8,这里只记录下Windows系统下的安装. 官方网站:http://www.imagemagick.org/script/index.php. ImageMa ...

  5. 转:ImageMagick +Jmagick安装

    原文来自于: 目录 一.ImageMagick介绍 二.安装支持库 三.在Linux上用源码编译安装ImageMagick与Jmagick 四.在Linux上使用yum安装ImageMagick与Jm ...

  6. Linux端图形处理工具ImageMagick在Centos上的安装

    一.安装背景程序要用到用户上传图片,编辑的功能,能进行旋转,裁剪,缩放等. 二.ImageMagick介绍 ImageMagick是用C语言开发图片处理程序.可以对图片进行改变大小.旋转.锐化.减色或 ...

  7. ImageMagick

    http://blog.csdn.net/lan861698789/article/details/7738383 1.官网 http://www.imagemagick.org/script/ind ...

  8. Linux安装ImageMagick与JMagick完成过程及配置

    原文地址:http://www.iitshare.com/linux-install-imagemagick-jmagick.html 一.安装背景 最近在服务器上部署了HapiCMS的产品,因为其对 ...

  9. Java使用jmagick处理图片遇到的异常

    java通过ImageMagick处理图片遇到问题: 下面异常都是我一个一个遇到的: 异常1: Exception in thread "main" java.lang.Unsat ...

随机推荐

  1. How to change system keyboard keymap layout on CentOS 7 Linux

    The easiest way to swap between keymaps and thus temporarily set keys to different language by use o ...

  2. docker 删除所有none的镜像

    docker images|grep none|awk '{print $3}'|xargs docker rmi

  3. select2插件用法

    1.修改默认查询方法,使其可以根据value查询 this.element.select2({ allowClear: true, matcher: function (term, text, ele ...

  4. UVa540

    //先输入队伍的个数 //用map建立数组将队伍序号和个人序号相互对应 //三条命令 #include <bits/stdc++.h> using namespace std; ; int ...

  5. java 日志体系(四)log4j 源码分析

    java 日志体系(四)log4j 源码分析 logback.log4j2.jul 都是在 log4j 的基础上扩展的,其实现的逻辑都差不多,下面以 log4j 为例剖析一下日志框架的基本组件. 一. ...

  6. GUI学习之九——QLineEdit的学习总结

    我们在前面学习了各种按钮控件,从这一章开始就是各种输入控件的学习. 首先要用的就是QLineEdit——单行编辑器, 一描述 QLineEdit是一个单行文本编辑器,允许用户输入和编辑单行纯文本.自带 ...

  7. Markdown 尝试

    目录 简介 参数模型 vs. 非参数模型 创新点 at the modeling level at the training procedure 模型结构 attention kernel Full ...

  8. python语法之正则

    1.正则表达式是用来干嘛的? 用来匹配字符串的  ,其中正则是意思是模糊匹配. 就其本质而言,正则表达式(或 RE)是一种小型的.高度专业化的编程语言,(在Python中)它内嵌在Python中,并通 ...

  9. 在datasnap 中使用unidac 访问数据(客户端)

    前面我们讲了如何使用unidac 在datasnap 的服务端访问数据库,今天大概讲一下客户端如何访问 前面做的服务器?其实这个客户端适合任何datasnap 服务端. 首先我们建一个应用,并加入一个 ...

  10. Java平台

    Java的平台无关性 不同的网络环境,操作系统 支持嵌入式设备 减少开发部署时间 Java自身的平台和语言 编译成class文件 可在Java虚拟机中运行,与外部环境无关(对虚拟机的依赖) 通过外部A ...