需求:

有一张位置大小的图片,现在需要根据这张原图得到指定尺寸的图片,且得到的图片要符合原先图片的比例,就是在原图的基础上等比例缩放得到图片后,在进行剪裁,这样保证得到的图片是原图的一部分,而不是将原图拉伸或着是压缩到指定的尺寸,这样的图片就会严重的失真,且不协调。

例如:

一张原图为600×400的图片,现在需求如下:

  1. 一张500×300的图片
  2. 一张700×400的图片
  3. 一张400×500的图片

注意:得到的图片不能是原图中的人物、景象有拉伸或压缩的感觉。

思路:

500×300的图片:可以看出宽度和高度都在原图的尺寸之内,但是为了多的得到原图的信息,可先将原图按照一定的比率压缩,压缩的比率min(500/600,300/400),为什么要选择这样的压缩比率呢?因为假如按照宽度比进行压缩,虽然得到的图片的宽度和要求的一致,但是那高度呢?有可能高度压缩之前确实是符合的,也就是大于目标图片的高度,但是枷锁之后,可能出现高度比需求的高度小,导致无法安装、要求截取图片,所以需要比较之后进行压缩,这样不会超出范围。

同理,不管要求的图片大小是否超出原图的大小,或是在原图的大小范围之内,都要先比较,然后再压缩,这样就可以保证得到的图片是放大或缩小到最合适并且包含最多的原图信息,不会变形。

计算压缩比例的核心算法

  1. /*
  2. * 核心算法,计算图片的压缩比
  3. */
  4. int w= buffer.getWidth();
  5. int h=buffer.getHeight();
  6. double ratiox = 1.0d;
  7. double ratioy = 1.0d;
  8. ratiox= w * ratiox / width;
  9. ratioy= h * ratioy / height;
  10. if( ratiox >= 1){
  11. if(ratioy < 1){
  12. ratiox = height * 1.0 / h;
  13. }else{
  14. if(ratiox > ratioy){
  15. ratiox = height * 1.0 / h;
  16. }else{
  17. ratiox = width * 1.0 / w;
  18. }
  19. }
  20. }else{
  21. if(ratioy < 1){
  22. if(ratiox > ratioy){
  23. ratiox = height * 1.0 / h;
  24. }else{
  25. ratiox = width * 1.0 / w;
  26. }
  27. }else{
  28. ratiox = width * 1.0 / w;
  29. }
  30. }
  31. /*
  32. * 对于图片的放大或缩小倍数计算完成,ratiox大于1,则表示放大,否则表示缩小
  33. */

这样,计算完的ratiox就是要压缩的比率。w、h是原图的width和height,而程序中的width和height是要得到图片的width和height。

在生成图片和其他的地方的程序是参考别人的,具体地址给忘了,再次谢过作者,以下是源代码:

  1. import java.awt.geom.AffineTransform;
  2. import java.awt.image.AffineTransformOp;
  3. import java.awt.image.BufferedImage;
  4. import java.io.File;
  5. import javax.imageio.ImageIO;
  6. public class UploadImg {
  7. String fromFileStr;
  8. String saveToFileStr;
  9. String sysimgfile;
  10. int width;
  11. int height;
  12. String suffix;
  13. /**
  14. * @param fromFileStr
  15. *            原始图片完整路径
  16. * @param saveToFileStr
  17. *            缩略图片保存路径
  18. * @param sysimgfilenNow
  19. *            处理后的图片文件名前缀
  20. *
  21. */
  22. public UploadImg(String fromFileStr, String saveToFileStr, String sysimgfile,String suffix,int width,int height) {
  23. this.fromFileStr = fromFileStr;
  24. this.saveToFileStr = saveToFileStr;
  25. this.sysimgfile = sysimgfile;
  26. this.width=width;
  27. this.height=height;
  28. this.suffix=suffix;
  29. }
  30. public boolean createThumbnail() throws Exception {
  31. // fileExtNmae是图片的格式 gif JPG 或png
  32. // String fileExtNmae="";
  33. File F = new File(fromFileStr);
  34. if (!F.isFile())
  35. throw new Exception(F
  36. + " is not image file error in CreateThumbnail!");
  37. File ThF = new File(saveToFileStr, sysimgfile +"."+suffix);
  38. BufferedImage buffer = ImageIO.read(F);
  39. /*
  40. * 核心算法,计算图片的压缩比
  41. */
  42. int w= buffer.getWidth();
  43. int h=buffer.getHeight();
  44. double ratiox = 1.0d;
  45. double ratioy = 1.0d;
  46. ratiox= w * ratiox / width;
  47. ratioy= h * ratioy / height;
  48. if( ratiox >= 1){
  49. if(ratioy < 1){
  50. ratiox = height * 1.0 / h;
  51. }else{
  52. if(ratiox > ratioy){
  53. ratiox = height * 1.0 / h;
  54. }else{
  55. ratiox = width * 1.0 / w;
  56. }
  57. }
  58. }else{
  59. if(ratioy < 1){
  60. if(ratiox > ratioy){
  61. ratiox = height * 1.0 / h;
  62. }else{
  63. ratiox = width * 1.0 / w;
  64. }
  65. }else{
  66. ratiox = width * 1.0 / w;
  67. }
  68. }
  69. /*
  70. * 对于图片的放大或缩小倍数计算完成,ratiox大于1,则表示放大,否则表示缩小
  71. */
  72. AffineTransformOp op = new AffineTransformOp(AffineTransform
  73. .getScaleInstance(ratiox, ratiox), null);
  74. buffer = op.filter(buffer, null);
  75. //从放大的图像中心截图
  76. buffer = buffer.getSubimage((buffer.getWidth()-width)/2, (buffer.getHeight() - height) / 2, width, height);
  77. try {
  78. ImageIO.write(buffer, suffix, ThF);
  79. } catch (Exception ex) {
  80. throw new Exception(" ImageIo.write error in CreatThum.: "
  81. + ex.getMessage());
  82. }
  83. return (true);
  84. }
  85. public static void main(String[] args) {
  86. UploadImg UI;
  87. boolean ss = false;
  88. try {
  89. UI = new UploadImg("C:\\Users\\Administrator\\Pictures\\111.jpg", "C:\\Users\\Administrator\\Pictures\\", "ps_low2","png",280,280);
  90. ss = UI.createThumbnail();
  91. if (ss) {
  92. System.out.println("Success");
  93. } else {
  94. System.out.println("Error");
  95. }
  96. } catch (Exception e) {
  97. System.out.print(e.toString());
  98. }
  99. }
  100. }

接下来测试几个例子:

原图1024*520:

要求得到尺寸:1000*500

  1. UI = new UploadImg("F:\\2.jpg", "F:\\", "ps","jpg",1000,500);

目标尺寸1000*700:

  1. UI = new UploadImg("F:\\2.jpg", "F:\\", "ps","jpg",1000,700);

目标尺寸:1100*600:

  1. UI = new UploadImg("F:\\2.jpg", "F:\\", "ps","jpg",1100,600);

目标尺寸600*500:

  1. UI = new UploadImg("F:\\2.jpg", "F:\\", "ps","jpg",600,500);

Java实现图片的裁剪的更多相关文章

  1. java对图片的裁剪(包括来自网络的图片)

    import java.awt.Rectangle; import java.awt.image.BufferedImage; import java.io.File; import java.io. ...

  2. Java实现图片的裁剪(包括透明背景)

    需求: 有一张位置大小的图片,现在需要根据这张原图得到指定尺寸的图片,且得到的图片要符合原先图片的比例,就是在原图的基础上等比例缩放得到图片后,在进行剪裁,这样保证得到的图片是原图的一部分,而不是将原 ...

  3. java多图片上传--前端实现预览--图片压缩 、图片缩放,区域裁剪,水印,旋转,保持比例。

    java多图片上传--前端实现预览 前端代码: https://pan.baidu.com/s/1cqKbmjBSXOhFX4HR1XGkyQ 解压后: java后台: <!--文件上传--&g ...

  4. Java实现图片裁剪预览功能

    在项目中.我们须要做些类似头像上传,图片裁剪的功能,ok看以下文章! 须要插件:jQuery Jcrop 后端代码: package org.csg.upload; import java.awt.R ...

  5. Android调用相机实现拍照并裁剪图片,调用手机中的相冊图片并裁剪图片

    在 Android应用中,非常多时候我们须要实现上传图片,或者直接调用手机上的拍照功能拍照处理然后直接显示并上传功能,以下将讲述调用相机拍照处理图片然后显示和调用手机相冊中的图片处理然后显示的功能,要 ...

  6. Java中图片压缩处理

    原文http://cuisuqiang.iteye.com/blog/2045855 整理文档,搜刮出一个Java做图片压缩的代码,稍微整理精简一下做下分享. 首先,要压缩的图片格式不能说动态图片,你 ...

  7. C# 图片的裁剪,两个图片合成一个图片

    图片的裁剪,两个图片合成一个图片(这是从网上摘的) /// <summary>         /// 图片裁剪,生成新图,保存在同一目录下,名字加_new,格式1.png  新图1_ne ...

  8. java获取图片原始尺寸

    java获取图片原始尺寸 URL url = null; InputStream is = null; BufferedImage img = null; try { url = new URL(pi ...

  9. android 照相或从相册获取图片并裁剪

    照相或从相册获取图片并裁剪 在android应用中很多时候都要获取图片(例如获取用户的头像)就需要从用户手机上获取图片.可以直接照,也可以从用户SD卡上获取图片,但获取到的图片未必能达到要求.所以要对 ...

随机推荐

  1. Java利用Redis实现消息队列

    应用场景 为什么要用redis?二进制存储.java序列化传输.IO连接数高.连接频繁 一.序列化 这里编写了一个java序列化的工具,主要是将对象转化为byte数组,和根据byte数组反序列化成ja ...

  2. BNUOJ 52509 Borrow Classroom

    最近公共祖先. 如果$A$到$1$的时间小于$B$到$C$再到$1$的时间,那么一定可以拦截. 如果上述时间相等,需要在到达$1$之前,两者相遇才可以拦截. #include<bits/stdc ...

  3. 洛谷P3538 [POI2012]OKR-A Horrible Poem [字符串hash]

    题目传送门 A Horrible Poem 题目描述 Bytie boy has to learn a fragment of a certain poem by heart. The poem, f ...

  4. BZOJ4653 [NOI2016]区间 [线段树,离散化]

    题目传送门 区间 Description 在数轴上有 n个闭区间 [l1,r1],[l2,r2],...,[ln,rn].现在要从中选出 m 个区间,使得这 m个区间共同包含至少一个位置.换句话说,就 ...

  5. FileBuffer-ImageBuffer 模拟PE

    这节课的重点是:模拟PE加载过程,按照运行的要求给FileBuffer拉伸放到内存当中,从 FileBuffer 到 ImageBuffer 再到 运行Buffer. PE  加载  过程: 根据si ...

  6. Eclipse中Tomcat 修改后台代码即时生效

    修改类后不用重启Tomcat就能自动生效,对于提高开发效率的帮助很大. server.xml 中节点定义时一般会有如下配置: <Context docBase="test1" ...

  7. Linux下安装scapy-python3

    安装scapy # pip3 install scapy-python3 # yum install libffi-devel # pip3 install cryptography 新建scapy软 ...

  8. Xamarin 2017.9.19更新

     Xamarin 2017.9.19更新   本次更新是添加Xamarin.iOS对iOS 11和Xcode 9的支持.Visual Studio 2017升级到15.3.5获得更新功能.Visual ...

  9. luogu P2619 [国家集训队2]Tree I

    题目链接 luogu P2619 [国家集训队2]Tree I 题解 普通思路就不说了二分增量,生成树check 说一下坑点 二分时,若黑白边权有相同,因为权值相同优先选白边,若在最有增量时出现黑白等 ...

  10. MySQL启动项提权

    关于MySQL的启动项提权,听其名知其意.就是将一段 VBS脚本导入到  C:\Documents and Settings\All Users\「开始」菜单\程序\启动 下,如果管理员重启了服务器, ...