需求:

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

例如:

一张原图为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. Redis实战(一)

    一.准备 Redis 是一个开源的使用ANSI C 语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value 数据库.Redis的出现,很大程度补偿了memcached这类key/valu ...

  2. Java-redis分布式锁 抢购秒杀系统 实现

    一.使用分布式锁要满足的几个条件: 系统是一个分布式系统(关键是分布式,单机的可以使用ReentrantLock或者synchronized代码块来实现) 共享资源(各个系统访问同一个资源,资源的载体 ...

  3. nhibernate 比较运算符

    比较运算符 HQL运算符 QBC运算符 含义 = Restrictions.eq() 等于 <> Restrictions.not(Exprission.eq()) 不等于 > Re ...

  4. JS 数组求 最大值、最小值、平均值以及求和方法

    function arrMaxNum2(arr) { return Math.max.apply(null, arr); } function arrMinNum2(arr) { return Mat ...

  5. 快速配置webpack多入口脚手架

    背景 当我们基于vue开发单个项目时,我们会init一个vue-cli,但当我们想在其他项目里共用这套模板时,就需要重新init一个,或者clone过来,这非常不方便,而且当多人开发时,我们希望所有的 ...

  6. 我的OI生涯 第五章

    我的OI生涯 第五章 千古诗才,蓬莱文章建安骨 一身傲骨,青莲居士谪仙人 李白追月逆江河 包黑斩龙顺民心 豪气压群雄,能使力士脱靴,贵妃捧砚; 仙才媲众美,不让参军俊逸,开府清新 我辈此中惟饮酒 先生 ...

  7. loj2480 [CEOI2017]One-Way Streets 边双+树上差分

    边双无法确定 缩完边双就是一棵树 树上差分随意弄一下吧... #include <vector> #include <cstdio> #include <cstring& ...

  8. 51nod2000 四边形分割平面 规律题

    观察样例,$ans(1) = 1, ans(2) = 10$,再手推一组,$ans(3) = 26$ 可以发现规律$ans(n) = (2n - 1)^2 + 1$ 如果还是没看出规律,那么打个程序去 ...

  9. 矩阵树定理(Matrix Tree)学习笔记

    如果不谈证明,稍微有点线代基础的人都可以在两分钟内学完所有相关内容.. 行列式随便找本线代书看一下基本性质就好了. 学习资源: https://www.cnblogs.com/candy99/p/64 ...

  10. [CodeForces-797F]Mice and Holes

    题目大意: 在一条直线上,有n个老鼠,m个洞. 每个老鼠i都有一个初始位置x[i]. 每个洞i都有一个固定位置p[i]和容量限制c[i]. 求所有老鼠都进洞的最小距离总和. 思路: 动态规划. 用f[ ...