Java实现图片的裁剪
需求:
有一张位置大小的图片,现在需要根据这张原图得到指定尺寸的图片,且得到的图片要符合原先图片的比例,就是在原图的基础上等比例缩放得到图片后,在进行剪裁,这样保证得到的图片是原图的一部分,而不是将原图拉伸或着是压缩到指定的尺寸,这样的图片就会严重的失真,且不协调。
例如:
一张原图为600×400的图片,现在需求如下:
- 一张500×300的图片
- 一张700×400的图片
- 一张400×500的图片
注意:得到的图片不能是原图中的人物、景象有拉伸或压缩的感觉。
思路:
500×300的图片:可以看出宽度和高度都在原图的尺寸之内,但是为了多的得到原图的信息,可先将原图按照一定的比率压缩,压缩的比率min(500/600,300/400),为什么要选择这样的压缩比率呢?因为假如按照宽度比进行压缩,虽然得到的图片的宽度和要求的一致,但是那高度呢?有可能高度压缩之前确实是符合的,也就是大于目标图片的高度,但是枷锁之后,可能出现高度比需求的高度小,导致无法安装、要求截取图片,所以需要比较之后进行压缩,这样不会超出范围。
同理,不管要求的图片大小是否超出原图的大小,或是在原图的大小范围之内,都要先比较,然后再压缩,这样就可以保证得到的图片是放大或缩小到最合适并且包含最多的原图信息,不会变形。
计算压缩比例的核心算法:
- /*
- * 核心算法,计算图片的压缩比
- */
- int w= buffer.getWidth();
- int h=buffer.getHeight();
- double ratiox = 1.0d;
- double ratioy = 1.0d;
- ratiox= w * ratiox / width;
- ratioy= h * ratioy / height;
- if( ratiox >= 1){
- if(ratioy < 1){
- ratiox = height * 1.0 / h;
- }else{
- if(ratiox > ratioy){
- ratiox = height * 1.0 / h;
- }else{
- ratiox = width * 1.0 / w;
- }
- }
- }else{
- if(ratioy < 1){
- if(ratiox > ratioy){
- ratiox = height * 1.0 / h;
- }else{
- ratiox = width * 1.0 / w;
- }
- }else{
- ratiox = width * 1.0 / w;
- }
- }
- /*
- * 对于图片的放大或缩小倍数计算完成,ratiox大于1,则表示放大,否则表示缩小
- */
这样,计算完的ratiox就是要压缩的比率。w、h是原图的width和height,而程序中的width和height是要得到图片的width和height。
在生成图片和其他的地方的程序是参考别人的,具体地址给忘了,再次谢过作者,以下是源代码:
- import java.awt.geom.AffineTransform;
- import java.awt.image.AffineTransformOp;
- import java.awt.image.BufferedImage;
- import java.io.File;
- import javax.imageio.ImageIO;
- public class UploadImg {
- String fromFileStr;
- String saveToFileStr;
- String sysimgfile;
- int width;
- int height;
- String suffix;
- /**
- * @param fromFileStr
- * 原始图片完整路径
- * @param saveToFileStr
- * 缩略图片保存路径
- * @param sysimgfilenNow
- * 处理后的图片文件名前缀
- *
- */
- public UploadImg(String fromFileStr, String saveToFileStr, String sysimgfile,String suffix,int width,int height) {
- this.fromFileStr = fromFileStr;
- this.saveToFileStr = saveToFileStr;
- this.sysimgfile = sysimgfile;
- this.width=width;
- this.height=height;
- this.suffix=suffix;
- }
- public boolean createThumbnail() throws Exception {
- // fileExtNmae是图片的格式 gif JPG 或png
- // String fileExtNmae="";
- File F = new File(fromFileStr);
- if (!F.isFile())
- throw new Exception(F
- + " is not image file error in CreateThumbnail!");
- File ThF = new File(saveToFileStr, sysimgfile +"."+suffix);
- BufferedImage buffer = ImageIO.read(F);
- /*
- * 核心算法,计算图片的压缩比
- */
- int w= buffer.getWidth();
- int h=buffer.getHeight();
- double ratiox = 1.0d;
- double ratioy = 1.0d;
- ratiox= w * ratiox / width;
- ratioy= h * ratioy / height;
- if( ratiox >= 1){
- if(ratioy < 1){
- ratiox = height * 1.0 / h;
- }else{
- if(ratiox > ratioy){
- ratiox = height * 1.0 / h;
- }else{
- ratiox = width * 1.0 / w;
- }
- }
- }else{
- if(ratioy < 1){
- if(ratiox > ratioy){
- ratiox = height * 1.0 / h;
- }else{
- ratiox = width * 1.0 / w;
- }
- }else{
- ratiox = width * 1.0 / w;
- }
- }
- /*
- * 对于图片的放大或缩小倍数计算完成,ratiox大于1,则表示放大,否则表示缩小
- */
- AffineTransformOp op = new AffineTransformOp(AffineTransform
- .getScaleInstance(ratiox, ratiox), null);
- buffer = op.filter(buffer, null);
- //从放大的图像中心截图
- buffer = buffer.getSubimage((buffer.getWidth()-width)/2, (buffer.getHeight() - height) / 2, width, height);
- try {
- ImageIO.write(buffer, suffix, ThF);
- } catch (Exception ex) {
- throw new Exception(" ImageIo.write error in CreatThum.: "
- + ex.getMessage());
- }
- return (true);
- }
- public static void main(String[] args) {
- UploadImg UI;
- boolean ss = false;
- try {
- UI = new UploadImg("C:\\Users\\Administrator\\Pictures\\111.jpg", "C:\\Users\\Administrator\\Pictures\\", "ps_low2","png",280,280);
- ss = UI.createThumbnail();
- if (ss) {
- System.out.println("Success");
- } else {
- System.out.println("Error");
- }
- } catch (Exception e) {
- System.out.print(e.toString());
- }
- }
- }
接下来测试几个例子:
原图1024*520:
要求得到尺寸:1000*500
- UI = new UploadImg("F:\\2.jpg", "F:\\", "ps","jpg",1000,500);
目标尺寸1000*700:
- UI = new UploadImg("F:\\2.jpg", "F:\\", "ps","jpg",1000,700);
目标尺寸:1100*600:
- UI = new UploadImg("F:\\2.jpg", "F:\\", "ps","jpg",1100,600);
目标尺寸600*500:
- UI = new UploadImg("F:\\2.jpg", "F:\\", "ps","jpg",600,500);
Java实现图片的裁剪的更多相关文章
- java对图片的裁剪(包括来自网络的图片)
import java.awt.Rectangle; import java.awt.image.BufferedImage; import java.io.File; import java.io. ...
- Java实现图片的裁剪(包括透明背景)
需求: 有一张位置大小的图片,现在需要根据这张原图得到指定尺寸的图片,且得到的图片要符合原先图片的比例,就是在原图的基础上等比例缩放得到图片后,在进行剪裁,这样保证得到的图片是原图的一部分,而不是将原 ...
- java多图片上传--前端实现预览--图片压缩 、图片缩放,区域裁剪,水印,旋转,保持比例。
java多图片上传--前端实现预览 前端代码: https://pan.baidu.com/s/1cqKbmjBSXOhFX4HR1XGkyQ 解压后: java后台: <!--文件上传--&g ...
- Java实现图片裁剪预览功能
在项目中.我们须要做些类似头像上传,图片裁剪的功能,ok看以下文章! 须要插件:jQuery Jcrop 后端代码: package org.csg.upload; import java.awt.R ...
- Android调用相机实现拍照并裁剪图片,调用手机中的相冊图片并裁剪图片
在 Android应用中,非常多时候我们须要实现上传图片,或者直接调用手机上的拍照功能拍照处理然后直接显示并上传功能,以下将讲述调用相机拍照处理图片然后显示和调用手机相冊中的图片处理然后显示的功能,要 ...
- Java中图片压缩处理
原文http://cuisuqiang.iteye.com/blog/2045855 整理文档,搜刮出一个Java做图片压缩的代码,稍微整理精简一下做下分享. 首先,要压缩的图片格式不能说动态图片,你 ...
- C# 图片的裁剪,两个图片合成一个图片
图片的裁剪,两个图片合成一个图片(这是从网上摘的) /// <summary> /// 图片裁剪,生成新图,保存在同一目录下,名字加_new,格式1.png 新图1_ne ...
- java获取图片原始尺寸
java获取图片原始尺寸 URL url = null; InputStream is = null; BufferedImage img = null; try { url = new URL(pi ...
- android 照相或从相册获取图片并裁剪
照相或从相册获取图片并裁剪 在android应用中很多时候都要获取图片(例如获取用户的头像)就需要从用户手机上获取图片.可以直接照,也可以从用户SD卡上获取图片,但获取到的图片未必能达到要求.所以要对 ...
随机推荐
- oracle 内连接、外连接、自然连接、交叉连接练习
oracle 内连接.外连接.自然连接.交叉连接练习 --查询员工信息 select * from emp; --查询部门信息 select * from dept; --需求:查询员工姓名.薪资和所 ...
- Codeforces Round #479 (Div. 3)
手速场2333,这群人贼牛逼!手速贼快! A. Wrong Subtraction time limit per test 1 second memory limit per test 256 m ...
- [HAOI2015]数组游戏
题目大意: 有一排n个格子,每个格子上都有一个白子或黑子,在上面进行游戏,规则如下: 选择一个含白子的格子x,并选择一个数k,翻转x,2x,...,kx格子上的子. 不能操作者负. 思路: 将“某个格 ...
- 【洛谷】P1631: 序列合并
P1631 序列合并 题目描述 有两个长度都是N的序列A和B,在A和B中各取一个数相加可以得到N2个和,求这N2个和中最小的N个. 输入输出格式 输入格式: 第一行一个正整数N: 第二行N个整数Ai ...
- Java高级架构师(一)第43节:Varnish简介、安装和基本使用
第一部分:Varnish简介 Varnish是一款开源的.高性能的HTTP加速器和反向代理服务器. Varnish反向代理的能力远不如Nginx. Varnish主要作用是HTTP的加速器,主要通过缓 ...
- VK Cup 2015 - Round 1 E. Rooks and Rectangles 线段树 定点修改,区间最小值
E. Rooks and Rectangles Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/problemse ...
- Android EditText 限制输入为ip类型
editText.setInputType(InputType.TYPE_CLASS_NUMBER); String digits = "0123456789."; editTex ...
- (转)Ext.Button点击事件的三种写法
转自:http://maidini.blog.163.com/blog/static/377627042008111061844345/ ExtJs的写法太灵活了,现在收集了关于Button点击事件的 ...
- LWIP轻量级TCPIP协议栈的移植
http://blog.csdn.net/ygrx/article/details/8020516 好久没有做过技术工作了,前几天因为一些需要,要在ST的OS20平台上进行了LWIP的移植,有一些心得 ...
- JS返回数组种类和个数(面试常问)
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...