文档章节

Java图片工具类完成图片的截取和任意缩放

Yemon
 Yemon
发布于 2016/05/17 10:32
字数 1766
阅读 37
收藏 0
点赞 2
评论 0

图片工具类,完成图片的截取和任意缩放:

直接code

package com.common.util;

import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.imageio.ImageIO;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.swt.graphics.Rectangle;

import com.gif4j.GifDecoder;
import com.gif4j.GifEncoder;
import com.gif4j.GifImage;
import com.gif4j.GifTransformer;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

/** 图片工具类,完成图片的截取
 * 
 * @author Beau Virgill */
public class IamgesResize
{
    private static Log log = LogFactory.getLog(IamgesResize.class);

    BufferedImage bufImage; // 原始图片
    int width; // 缩放的宽度
    int height; // 缩放的高度

    public IamgesResize()
    {
        // TODO Auto-generated constructor stub
    }

    public IamgesResize(String srcPath, int width, int height)
    {
        this.width = width;
        this.height = height;
        try
        {
            this.bufImage = ImageIO.read(new File(srcPath));
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    /** 实现图像的等比缩放和缩放后的截取,如果高度的值和宽度一样,则缩放按设置的值缩放 (只控制宽度的大小,高度的值设置不生效(只有高度的值和宽度的一样才生效), 高度自动按比例缩放;如果缩放的图片小于你设置的值则保存原图大小)
     * 
     * @param inFilePath
     *            要缩放图片文件的路径
     * @param outFilePath
     *            缩放后保存图片输出的路径
     * @param width
     *            要截取宽度
     * @param hight
     *            要截取的高度
     * @throws Exception */

    public static void zoomOutImage(String inFilePath, String outFilePath, int width, int hight, boolean smooth)
            throws Exception
    {
        int maxHight = 500; // 设置最大的图片高度;

        File file = new File(inFilePath);
        InputStream in = new FileInputStream(file);
        File saveFile = new File(outFilePath);
        BufferedImage srcImage = ImageIO.read(in);

        String gif = inFilePath.substring(inFilePath.lastIndexOf(".") + 1, inFilePath.length());

        if ((gif.equals("gif") || gif.equals("GIF")) && smooth == true) // gif动态图片的处理
        {
            IamgesResize.getGifImage(inFilePath, outFilePath, width, hight, true);
        }
        else
        {
            // 如果宽度和高度一样 或者图片的规格为 images_120 时不按等比缩放,如果需要等比缩放, 则将下面的 if 语句注释即可
            if (width != hight && !outFilePath.contains("images_120"))
            {
                double sx = (double) width / srcImage.getWidth();
                hight = (int) (srcImage.getHeight() * sx);
            }
            log.info("原理图片路径------>" + inFilePath);
            log.info("保存图片新路径------>" + saveFile);

            if (width > 0 || hight > 0)
            {
                // 原图的大小
                int sw = srcImage.getWidth();
                int sh = srcImage.getHeight();
                log.info("原图宽=" + sw);
                log.info("原图高=" + sh);
                // 如果原图像的大小小于要缩放的图像大小,直接将要缩放的图像复制过去
                if (sw > width && sh > hight)
                {
                    srcImage = rize(srcImage, width, hight);
                }
                else
                {
                    log.info("原图片的大小小于要缩放的大小,不需要缩小");
                    String fileName = saveFile.getName();
                    String formatName = fileName.substring(fileName.lastIndexOf('.') + 1);
                    ImageIO.write(srcImage, formatName, saveFile);
                    return;
                }
            }
            // 缩放后的图像的宽和高
            int w = srcImage.getWidth();
            int h = srcImage.getHeight();
            log.info("缩小图片宽度= " + w);
            log.info("缩小图片高度= " + h);

            // 如果缩放后的图像和要求的图像宽度一样,就对缩放的图像的高度进行截取
            if (w == width)
            {
                // 计算 X轴坐标
                int x = 0;

                // 如果图片超过指定高度则截取一定的高度
                if (h >= maxHight && width != 600) // 图片为600 的不需要截取高度
                {
                    int y = h / 2 - hight / 2;
                    saveSubImage(srcImage, new Rectangle(x, y, width, maxHight), saveFile);
                }
                else
                {
                    int y = h / 2 - hight / 2;
                    saveSubImage(srcImage, new Rectangle(x, y, width, hight), saveFile);
                }

            }
            // 否则如果是缩放后的图像的高度和要求的图像高度一样,就对缩放后的图像的宽度进行截取
            else if (h == hight)
            {
                // 计算X轴坐标
                int x = w / 2 - width / 2;
                int y = 0;
                saveSubImage(srcImage, new Rectangle(x, y, width, hight), saveFile);
            }
            in.close();
        }
    }

    /** @param srcPath
     *            图片的绝对路径
     * @param width
     *            图片要缩放的宽度
     * @param height
     *            图片要缩放的高度
     * @param rizeType
     *            图片要缩放的类型(1:宽度固定,高度自动 2:按宽度和高度比例缩小)
     * @return */
    public static BufferedImage rize(BufferedImage srcBufImage, int width, int height)
    {
        BufferedImage bufTarget = null;
        int type = srcBufImage.getType();
        double sx = (double) width / srcBufImage.getWidth();
        double sy = (double) height / srcBufImage.getHeight();

        log.info("w=" + sx);
        log.info("h=" + sx);

        if (type == BufferedImage.TYPE_CUSTOM)
        {
            ColorModel cm = srcBufImage.getColorModel();
            WritableRaster raster = cm.createCompatibleWritableRaster(width, height);
            boolean alphaPremultiplied = cm.isAlphaPremultiplied();
            bufTarget = new BufferedImage(cm, raster, alphaPremultiplied, null);
        }
        else
        {
            bufTarget = new BufferedImage(width, height, type);
        }

        Graphics2D g = bufTarget.createGraphics();
        g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        g.drawRenderedImage(srcBufImage, AffineTransform.getScaleInstance(sx, sy));
        g.dispose();
        return bufTarget;
    }

    /** 实现缩放后的截图
     * 
     * @param image
     *            缩放后的图像
     * @param subImageBounds
     *            要截取的子图的范围
     * @param subImageFile
     *            要保存的文件
     * @throws IOException */
    private static void saveSubImage(BufferedImage image, Rectangle subImageBounds, File subImageFile)
            throws IOException
    {
        if (subImageBounds.x < 0 || subImageBounds.y < 0 || subImageBounds.width - subImageBounds.x > image.getWidth()
                || subImageBounds.height - subImageBounds.y > image.getHeight())
        {
            log.info("Bad   subimage   bounds");
            return;
        }
        BufferedImage subImage = image.getSubimage(subImageBounds.x, subImageBounds.y, subImageBounds.width,
                subImageBounds.height);
        String fileName = subImageFile.getName();
        String formatName = fileName.substring(fileName.lastIndexOf('.') + 1);
        ImageIO.write(subImage, formatName, subImageFile);
    }

    /** 针对书签截屏的等比缩放(等比缩放,不失真)
     * 
     * @param src
     *            源图片文件完整路径
     * @param dist
     *            目标图片文件完整路径
     * @param width
     *            缩放的宽度
     * @param heightw
     *            缩放的高度 */
    public static void createThumbnail(String src, String dist, float width, float height)
    {
        try
        {
            File srcfile = new File(src);
            if (!srcfile.exists())
            {
                log.error("文件不存在");
                return;
            }
            BufferedImage image = ImageIO.read(srcfile);

            // 获得缩放的比例
            double ratio = 1.0;
            // 判断如果高、宽都不大于设定值,则不处理
            if (image.getHeight() > height || image.getWidth() > width)
            {
                if (image.getHeight() > image.getWidth())
                {
                    ratio = height / image.getHeight();
                }
                else
                {
                    ratio = width / image.getWidth();
                }
            }
            // 计算新的图面宽度和高度
            int newWidth = (int) (image.getWidth() * ratio);
            int newHeight = (int) (image.getHeight() * ratio);

            BufferedImage bfImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);
            bfImage.getGraphics().drawImage(image.getScaledInstance(newWidth, newHeight, Image.SCALE_SMOOTH), 0, 0,
                    null);

            FileOutputStream os = new FileOutputStream(dist);
            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(os);
            encoder.encode(bfImage);
            os.close();
            log.info("创建缩略图成功");
        }
        catch (Exception e)
        {
            log.error("创建缩略图发生异常" + e.getMessage());
        }
    }

    /** 实现图像的等比缩放和缩放后的截取,如果高度的值和宽度一样,则缩放按设置的值缩放 (只控制宽度的大小,高度的值设置不生效(只有高度的值和宽度的一样才生效), 高度自动按比例缩放;如果缩放的图片小于你设置的值则保存原图大小)
     * 如果要缩放的宽度和高度相等则不按比例缩放;直接缩小图片
     * 
     * @param filepath
     *            要缩放图片文件的路径
     * @param saveFilePath
     *            缩放后保存图片输出的路径
     * @param imgWidth
     *            要缩放的宽度
     * @param imHeight
     *            要缩放的高度
     * @return
     * @throws Exception */
    public static boolean readPicfile(String filepath, String saveFilePath, int imgWidth, int imHeight)
            throws Exception
    {
        File file = new File(filepath);

        if (file.isDirectory())
        { // 如果path表示的是否是文件夹,是返回true
            log.info("文件夹");
            String[] filelist = file.list();
            log.info("总图片个数=" + filelist.length);
            int count = 0;
            for (int i = 0; i < filelist.length; i++)
            {
                File readfile = new File(filepath + filelist[i]);
                if (!readfile.isDirectory())
                {
                    log.info("absolutepath=" + readfile.getAbsolutePath());
                    log.info("imgName=" + readfile.getName());
                    String imgfuffix = readfile.getName().substring(readfile.getName().lastIndexOf(".") + 1,
                            readfile.getName().length()); // 获取文件的后缀
                    // 是图片类型的才执行缩放
                    if (isFromImgUrl(imgfuffix))
                    {
                        count++;
                        IamgesResize.zoomOutImage(filepath + readfile.getName(), saveFilePath + readfile.getName(),
                                imgWidth, imHeight, true);
                        IamgesResize.createThumbnail(filepath + readfile.getName(), saveFilePath + readfile.getName(),
                                imgWidth, imHeight);
                    }

                }
            }
        }
        return true;
    }

    /** gif图片缩放有动态效果
     * 
     * @param srcImg
     *            原始文件
     * @param destImg
     *            要保存的文件
     * @param width
     *            宽度
     * @param height
     *            高度
     * @param smooth
     * @throws Exception */
    public static void getGifImage(String srcImg, String destImg, int width, int hight, boolean smooth)
            throws Exception
    {
        try
        {
            File file = new File(srcImg);
            File saveFile = new File(destImg);
            InputStream in = new FileInputStream(srcImg);
            BufferedImage srcImage = ImageIO.read(in);

            GifImage gifImage = GifDecoder.decode(file);// 创建一个GifImage对象.
            if (width > 0 || hight > 0)
            {
                // 原图的大小
                int sw = srcImage.getWidth();
                int sh = srcImage.getHeight();

                if (width == hight)
                {
                }
                else if (sw > width)
                {
                    double sx = (double) width / srcImage.getWidth();
                    hight = (int) (srcImage.getHeight() * sx);
                }
                else
                {
                    width = sw;
                    hight = sh;
                }
            }
            // 1.缩放重新更改大小.
            GifImage resizeIMG = GifTransformer.resize(gifImage, width, hight, true);
            // 2.剪切图片演示.
            // Rectangle rect = new Rectangle(0,0,200,200);
            // GifImage cropIMG = GifTransformer.crop(gifImage, rect);
            // 3.按比例缩放
            // GifImage resizeIMG = GifTransformer.scale(gifImage, 1.0, 1.0,true);//参数需要double型
            // 4.其他的方法.还有很多,比如水平翻转,垂直翻转 等等.都是GifTransformer类里面的.
            GifEncoder.encode(resizeIMG, saveFile);
        }
        catch (IOException e)
        {
            e.printStackTrace();
            log.debug("保存失败(该图为修改过得gif图片),重新保存一次。");
            IamgesResize.zoomOutImage(srcImg, destImg, width, hight, false);
        }

    }

    /** 判断网址是不是图片类型。
     * 
     * @param fromUrl
     * @return */
    public static boolean isFromImgUrl(String imgfuffix)
    {
        boolean isImage = false;

        // 支持的图片后缀。
        String[] imgSuffixs = { "jpg", "JPG", "jpeg", "JPEG", "gif", "GIF", "png", "PNG", "bmp", "BMP" };
        for (int i = 0; i < imgSuffixs.length; i++)
        {
            if (imgfuffix.equals(imgSuffixs[i]))
            {
                isImage = true;
                break;
            }
        }
        return isImage;
    }
}



本文转载自:http://blog.csdn.net/hj7jay/article/details/51279647

共有 人打赏支持
Yemon
粉丝 10
博文 320
码字总数 22799
作品 0
广州
架构师
JAVA读取Oracle中的blob图片字段并显示

整个流程分为四步,连接oracle数据库 -> 读取blob图片字段 -> 对图片进行缩放 ->把图片展示在jsp页面上。 下面进行详细描述: 1. java连接Oracle 注:数据库是Oracle10g版本为10.2.0, 在数据...

underA
2013/03/15
0
1
android 加载大图片时报OOM的解决方案(源码)

在Android中:   1.一个进程的内存可以由2个部门组成:java 施用内存 ,C 施用内存 ,这两个内存的和必需小于16M,不然就会出现各人熟悉的OOM,这个就是熬头种OOM的情况。   2.一朝内存分...

天下杰论
2013/11/24
0
0
使用 Grapicmagick 和 Im4java 处理图片

ImageMagick是个图片处理工具可以安装在绝大多数的平台上使用,Linux、Mac、Windows都没有问题。GraphicsMagick是在ImageMagick基础上的另一个项目,大大提高了图片处理的性能,在linux平台上...

voole
05/07
0
0
有效解决Android加载大图片时内存溢出的问题

首先解析一下基本的知识: 位图模式,bitmap颜色位数是1位 灰度模式,bitmap颜色位数是8位,和256色一样 RGB模式,bitmap颜色位数是24位 在RGB模式下,一个像素对应的是红、绿、蓝三个字节 ...

蜗牛TT
2012/10/24
0
3
Android图片内存优化的几点心得

Android图片内存优化的几点心得 Admin 2012年6月24日名人名言:时间就是生命,时间就是速度,时间就是力量。——郭沫若 1、将图片转化为缩略图再加载: 1 BitmapFactory.Options options = ...

Thanks
2012/11/20
0
0
Android-Universal-Image-Loader 图片异步加载类库的使用(超详细配置)

这个图片异步加载并缓存的类已经被很多开发者所使用,是最常用的几个开源库之一,主流的应用,随便反编译几个火的项目,都可以见到它的身影。 一、介绍 Android-Universal-Image-Loader是一个...

Thanks
2014/04/13
0
0
Android有效解决加载大图片时内存溢出问题VMRuntime

解决办法:在以下界面中选择“Project Build Target”中选择“Android 2.2”版本即可。若是选择2.3.1或2.3.3都邑报错。 尽量不要使用setImageBitmap或setImageResource或BitmapFactory.decod...

带梦想一7飞
2013/05/23
0
0
Android有效解决加载大图片时内存溢出的问题

尽量不要使用setImageBitmap或setImageResource或BitmapFactory.decodeResource来设置一张大图, 因为这些函数在完成decode后,最终都是通过java层的createBitmap来完成的,需要消耗更多内存...

Thanks
2013/01/27
0
1
Android有效解决加载大图片时内存溢出的问题

尽量不要使用setImageBitmap或setImageResource或BitmapFactory.decodeResource来设置一张大图, 因为这些函数在完成decode后,最终都是通过java层的createBitmap来完成的,需要消耗更多内存...

带梦想一7飞
2012/07/03
0
0
高清缩略图之Thumbnailator

搞网站开发,经常要用到的一个功能是生成缩略图。如果对缩略图的质量要求不高,直接用JDK提供的Image API就可以搞定,简单示例: File _file = new File("/Order005-0001.jpg"); //读入文件I...

一剑风徽
2012/11/18
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Python PIPEs

https://www.python-course.eu/pipes.php https://www.tutorialspoint.com/python/os_pipe.htm

zungyiu
3分钟前
0
0
gRPC学习笔记

gRPC编程流程 1. proto文件定义 proto文件用于定义需要通过gRPC生成的接口,可以理解为接口定义文档 2. 通过构建工具生成服务基类代码-Maven或Gradle 3. 服务端开发 服务端实现类须实现通过构...

OSC_fly
23分钟前
0
0
Docker Mac (三) Dockerfile 及命令

Dockerfile 最近学习docker的时候,遇到一件怪事,关于docker镜像可能会被破坏,还不知道它会有此措施 所以需要了解构建Dockerfile的正确方法 Dockerfile是由一系列命令和参数构成的脚本,这些命...

___大侠
50分钟前
0
0
Android Studio+NDK+Cmake 移植FFmpeg-4.0.2命令行工具

一、编译 参考大神的帖子,亲测一次编译成功:https://blog.csdn.net/bobcat_kay/article/details/80889398 鉴于以前查文档的经验,这里附上编写例子的时间:2018年7月22日 我用的是ubantu,...

她叫我小渝
50分钟前
0
0
mysql创建数据库

登录MYSQL mysql -u root -p 脚本创建数据库WeChat,并制定默认的字符集是utf8mb4。 CREATE DATABASE Wechat DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_general_ci; 授权 grant all......

niithub
今天
0
0
svn: Unable to connect to a repository URL 的解决方案

错误图示: 解决办法:清除本地保存的授权信息; 1:右键点击本地文件夹,选择设置; TortoiseSVN -> Settings 2:在弹出的对话框中选择 Saved Data, 右侧选择:授权地方清理所有。 然后点确...

宁哥实战课堂
今天
1
0
sleep与wait的区别

Thread.sleep(XXX)方法消耗CPU吗? 这个知识点是我之前认识一直有错误的一个知识点,在我以前的认识里面,我一直认为Thread.sleep(1000)的这一秒钟的时间内,线程的休眠是一直占用着CPU的时间...

码代码的小司机
今天
1
0
20位活跃在Github上的国内技术大牛 leij 何小鹏 亚信

本文列举了20位在Github上非常活跃的国内大牛,看看其中是不是很多熟悉的面孔? 1. lifesinger(玉伯) Github主页: https://github.com/lifesinger 微博:@ 玉伯也叫射雕 玉伯(王保平),...

海博1600
今天
1
0
Mybatis收集配置

一、Mybatis取Clob数据 1、Mapper.xml配置 <resultMap type="com.test.User" id="user"> <result column="id" property="id"/> <result column="json_data" property="jsonData" ......

星痕2018
今天
1
0
centos7设置以多用户模式启动

1、旧版本linux系统修改inittab文件,在新版本执行vi /etc/inittab 会有以下提示 # inittab is no longer used when using systemd. # # ADDING CONFIGURATION HERE WILL HAVE NO EFFECT ON......

haha360
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部