JMagick实现基本图像处理的类实例

本文实例讲述了JMagick实现基本图像处理的类。分享给大家供大家参考。具体分析如下:

JMagick是一个开源API,利用JNI(Java Native Interface)技术实现了对 ImageMagick API的Java访问接口,因此也将比纯Java实现的图片操作函数在速度上要快。

/**
 * JMagickHandler.java
 *
 * Author: Winter Lau
 * 2007-7-11
 */
package com.eportal.img;
import java.awt.Dimension;
import java.io.File;
import org.apache.commons.io.FileUtils;
import com.gif4j.GifDecoder;
import com.gif4j.GifEncoder;
import com.gif4j.GifImage;
import com.gif4j.GifTransformer;
import dlog.common.util.StringUtils;
import magick.ImageInfo;
import magick.MagickException;
import magick.MagickImage;
/**
 * 使用JMagick进行图像处理
 */
class JMagickHandler {
  private final static int DEFAULT_QUALITY = 90;
  protected JMagickHandler(){}
  private final static ThreadLocal<MyMagickImage> tLocal = new ThreadLocal<MyMagickImage>();
  private String lastSrc = null;
  /**
   * 清除线程本地存储信息
   */
  private synchronized MyMagickImage getMagickImage(String src) throws Exception {
    MyMagickImage mi = tLocal.get();
    if(mi != null && StringUtils.equals(src, lastSrc))
      return mi;
    else if(mi != null)
      tLocal.remove();
    this.lastSrc = src;
    ImageInfo info = new ImageInfo(src);
    mi = new MyMagickImage(info);
    tLocal.set(mi);
    return mi;
  }
  @Override
  public void cleanup() {
    MyMagickImage mi = tLocal.get();
    if(mi != null)
      mi.destroyImages();
    tLocal.remove();
  }
  @Override
  public ImageExtInfo getImageInfo(String src) throws Exception {
    try{
      MagickImage image = this.getMagickImage(src);
      ImageExtInfo ext = new ImageExtInfo();
      Dimension dim = image.getDimension();
      ext.setWidth((int)dim.getWidth());
      ext.setHeight((int)dim.getHeight());
      ext.setSize(image.sizeBlob());
      ext.setAnimated(image.isAnimatedImage());
      return ext;
    }catch(MagickException e){
      return new PureJavaHandler().getImageInfo(src);
    }
  }
  private final static boolean hasUnicode(String str){
    return str.getBytes().length != str.length();
  }
  @Override
  public void resize(String src, String dest, int width, int height, int quality) throws Exception {
    boolean u_src = hasUnicode(src);
    MyMagickImage image;
    File srctmp = null;
    if(u_src){
      srctmp = File.createTempFile("jmagick_s_" + src.hashCode(), null);
      FileUtils.copyFile(new File(src), srctmp);
      image = this.getMagickImage(srctmp.getAbsolutePath());
    }
    else
      image = this.getMagickImage(src);
    image.getImageInfo().setQuality((quality>0)?quality:DEFAULT_QUALITY);
    MagickImage scaledimage = null;
    try{
      if(image.isAnimatedImage()){
        GifImage gifImage = GifDecoder.decode(new File(src));
        GifImage newGif = GifTransformer.resize(gifImage, width, height, false);
        GifEncoder.encode(newGif, new File(dest));
      }
      else{//others
        scaledimage = image.scaleImage(width, height);
        scaledimage.setImageFormat("JPEG");
        scaledimage.profileImage("*", null);
        boolean u_dest = hasUnicode(dest);
        if(u_dest){
          File tmp = File.createTempFile("jmagick_d_" + dest.hashCode(), null);
          scaledimage.setFileName(tmp.getAbsolutePath());
          scaledimage.writeImage(image.getImageInfo());
          FileUtils.copyFile(tmp, new File(dest));
          FileUtils.forceDelete(tmp);
        }
        else{
          scaledimage.setFileName(dest);
          scaledimage.writeImage(image.getImageInfo());
        }
      }
    }finally{
      if(srctmp != null) FileUtils.forceDelete(srctmp);
      if(scaledimage != null)
        scaledimage.destroyImages();
    }
  }
  @Override
  public void rotate(String src, String dest, double degrees) throws Exception {
    boolean u_src = hasUnicode(src);
    MyMagickImage image;
    File srctmp = null;
    if(u_src){
      srctmp = File.createTempFile("jmagick_s_" + src.hashCode(), null);
      FileUtils.copyFile(new File(src), srctmp);
      image = this.getMagickImage(srctmp.getAbsolutePath());
    }
    else
      image = this.getMagickImage(src);
    try{
      MagickImage rotateImg = image.rotateImage(degrees);
      rotateImg.profileImage("*", null);

      boolean u_dest = hasUnicode(dest);
      if(u_dest){
        File tmp = File.createTempFile("jmagick_d_" + dest.hashCode(), null);
        rotateImg.setFileName(tmp.getAbsolutePath()); // convert to png
        rotateImg.writeImage(image.getImageInfo());
        rotateImg.destroyImages();
        FileUtils.copyFile(tmp, new File(dest));
        FileUtils.forceDelete(tmp);
      }
      else{
        rotateImg.setFileName(dest); // convert to png
        rotateImg.writeImage(image.getImageInfo());
        rotateImg.destroyImages();
      }
    }finally{
      if(srctmp != null)
        FileUtils.forceDelete(srctmp);
    }
  }
  private static class MyMagickImage extends MagickImage {
    private ImageInfo imageInfo;
    public ImageInfo getImageInfo() {
      return imageInfo;
    }
    public MyMagickImage(ImageInfo info) throws MagickException{
      super(info);
      this.imageInfo = info;
    }
  }
  @Override
  public void cropImage(String src, int width, int height, int point,
      int point2, String dst) throws Exception {
    // TODO Auto-generated method stub
  }
}

希望本文所述对大家的java程序设计有所帮助。

(0)

相关推荐

  • Java图像处理工具类

    本工具类的功能:缩放图像.切割图像.图像类型转换.彩色转黑白.文字水印.图片水印等 复制代码 代码如下: package net.kitbox.util; import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.Re

  • java图形界面之布局设计

    在界面设计中,一个容器要放置许多组件,为了美观,为组件安排在容器中的位置,这就是布局设计.java.awt中定义了多种布局类,每种布局类对应一种布局的策略.常用的有以下布局类: •FlowLayout,依次放置组件. •BoarderLayout,将组件放置在边界上. •CardLayout,将组件像扑克牌一样叠放,而每次只能显示其中一个组件. •GridLayout,将显示区域按行.列划分成一个个相等的格子,组件依次放入这些格子中. •GridBagLayout,将显示区域划分成许多矩形小单元

  • 开发基于Java的图形用户界面

    SWT(Standard Widget Toolkit)是IBM推出的"基于java"的图形界面开发库,我之所以说它是"基于java"的意思是程序员编写代码的时候是使用java语言,事实上SWT的底层实现是C语言完成的.但是这些对程序员是透明的. 我们使用SWT开发GUI程序的时候,直接用SWT API来写.事实上很多java的代码是通过JNI去掉用C代码来实现的.针对不同的平台每个类有不同的实现方式,这篇文章的目的不在于讲述SWT的设计原理,如果你对这些感兴趣的话

  • java图形界面编程之模拟血压计

    复制代码 代码如下: package GraphicsCanvas; import java.awt.BorderLayout;import java.awt.Canvas;import java.awt.Color;import java.awt.Graphics;import java.awt.Image;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import javax.swing.JBut

  • java数字图像处理基础使用imageio写图像文件示例

    一个BufferedImage的像素数据储存在Raster中,ColorModel里面储存颜色空间,类型等信息,当前Java只支持一下三种图像格式- JPG,PNG,GIF,如何向让Java支持其它格式,首先要 完成Java中的图像读写接口,然后打成jar,加上启动参数- Xbootclasspath/pnewimageformatIO.jar即可. Java中如何读写一个图像文件,使用ImageIO对象即可.读图像文件的代码如下: 复制代码 代码如下: File file = new File

  • Java在Linux下 不能处理图形的解决办法 分享

    java在图形处理时调用了本地的图形处理库.在利用Java作图形处理(比如:图片缩放,图片签名,生成报表)时,如果运行在windows上不会出问题.如果将程序移植到Linux/Unix上的时候有可能出现图形不能显示的错误. 提示信息:"Can't connect to X11 window server"这是由于Linux的图形处理需要一个X Server服务器. 解决办法: 1.如果服务器上安装有图形界面,可以通过设置环境变量:DISPALY=127.0.0.1:0.0解决. 2.

  • Java计算几何图形面积的实例代码

    对于每个几何图形而言,都有一些共同的属性,如名字.面积等,而其计算面积的方法却各不相同.为了简化开发,请编写程序,定义一个超类来实现输入名字的方法,并使用抽象方法来计算面积. 思路分析: 所谓超类就是抽象父类,该抽象类中有两个方法,分别用来获取图形的名称和图形的面积.要获得图形的名称,通过类的getClass().getSimpleName()方法可以实现:要获得图形的面积,因为计算面积的方法各不相同,所以该方法是个抽象方法.定义一个子类表示圆形,圆形的半径通过构造方法获得,圆形的面积通过重写超

  • 关于java 图形验证码的解决方法

    复制代码 代码如下: package cn.response; import java.awt.Color;import java.awt.Font;import java.awt.Graphics;import java.awt.Graphics2D;import java.awt.image.BufferedImage;import java.io.IOException;import java.util.Random; import javax.imageio.ImageIO;import

  • Java应用程序中创建图像

    合成图像 您不必从文件中读取所有的图像 - 您可以创建自己的图像.要创建自己的图像,最灵活的方法是用一个 BufferedImage 对象,它是 Image 类的一个子类,它把图像数据存储在一个可以被访问的缓冲区中.它还支持各种存储像素数据的方法:使用或不使用 alpha 通道.不同种类的颜色模型以及颜色组件的各种精确度.ColorModel 类提供一种灵活的方法定义各种颜色模型,以和 BufferedImage 对象一起使用.为了理解颜色模型工作的基本知识,我们将只使用一个缺省的颜色模型,其颜

  • JMagick实现基本图像处理的类实例

    本文实例讲述了JMagick实现基本图像处理的类.分享给大家供大家参考.具体分析如下: JMagick是一个开源API,利用JNI(Java Native Interface)技术实现了对 ImageMagick API的Java访问接口,因此也将比纯Java实现的图片操作函数在速度上要快. /** * JMagickHandler.java * * Author: Winter Lau * 2007-7-11 */ package com.eportal.img; import java.aw

  • Android常用正则表达式验证工具类(实例代码)

    东西不多,但一般项目够用了. public class RegularUtil { //身份证 public static final String REGEX_ID_CARD = "^[1-9]\\d{5}[1-9]\\d{3}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}([0-9]|X)$"; //验证邮箱 public static final String REGEX_EMAIL = "^([a-z0-9A-Z]+[-|\\

  • Ruby类实例变量、类实例方法和类变量、类方法的区别

    在Ruby中类实例变量.类实例方法和类变量.类方法的区别比较微妙,而且用法也有相当的区别.本文探讨一下他们的定义和基本的使用场景,以抛砖引玉...   一.类实例变量和类变量   类变量大家都很熟悉了,就是在类定义中用@@开头的变量.类变量是用于存储类的全局信息,它只属于类,不同与类实例变量(即用@开头定义的变量)每一个类的对象都有一份数据. 类变量是可以被继承的,也就是说如果我们派生一个子类,那么在子类中是可以访问父类的类变量的.子类和父类共享一份数据,对一个类的修改会反映到另一个类中.如下边

  • HttpUtils 发送http请求工具类(实例讲解)

    废话不多说,直接上代码 import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFac

  • Java集合ArrayDeque类实例分析

    Java集合ArrayDeque类实例分析 前言 ArrayDeque类是双端队列的实现类,类的继承结构如下面,继承自AbastractCollection(该类实习了部分集合通用的方法,其实现了Collection接口),其实现的接口Deque接口中定义了双端队列的主要的方法,比如从头删除,从尾部删除,获取头数据,获取尾部数据等等. public class ArrayDeque<E> extends AbstractCollection<E> implements Deque&

  • 动态创建类实例代码

    例如: import mymodule myobject = mymodule.myclass() 或者 from mymodule import myclass myobject = myclass() 如果要在程序中动态地创建类实例,也一样要分两步走,例如: m = __import__('mymodule') c = getattr(m, 'myclass') myobject = c() 但是要注意:如果myclass并不在mymodule的自动导出列表中(__all__),则必须显式地

  • C++实现String类实例代码

    C++实现String类实例代码 这是一道十分经典的面试题,可以短时间内考查学生对C++的掌握是否全面,答案要包括C++类的多数知识,保证编写的String类可以完成赋值.拷贝.定义变量等功能. #include<iostream> using namespace std; class String { public: String(const char *str=NULL); String(const String &other); ~String(void); String &am

  • Asp.Net中Cache操作类实例详解

    本文以一个Asp.Net的Cache操作类实例代码来详细描述了cache缓存的结构及实现方法,完整代码如下所示: /// <head> /// <function> /// 存储类(存储UserInfo信息) /// </function> /// <description> /// 用Cache存储用户信息 /// 在指定间隔(TimeOut)内取,则可以从Cache中取, /// 如果超出存储时间,则从数据库取用户信息数据 /// 作為所有用户信息的存儲

  • PHP加密解密类实例代码

    关键代码如下所示: <?php function i_array_column($input, $columnKey, $indexKey=null){ if(!function_exists('array_column')){ $columnKeyIsNumber = (is_numeric($columnKey))?true:false; $indexKeyIsNull = (is_null($indexKey))?true :false; $indexKeyIsNumber = (is_n

  • php读取qqwry.dat ip地址定位文件的类实例代码

    实例如下: <?php // +---------------------------------------------------------------------- // | // +---------------------------------------------------------------------- // | // +---------------------------------------------------------------------- cla

随机推荐