需求:

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

例如:

一张原图为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. ZOJ 3613 Wormhole Transport

    斯坦纳树,$dp$. 先求出每个状态下连通的最小花费,因为可以是森林,所以$dp$一下. #include<bits/stdc++.h> using namespace std; int ...

  2. React Native 系列(四)

    前言 本系列是基于React Native版本号0.44.3写的.RN支持CSS中的布局属性,因此可以使用CSS布局属性,这里就不详细地讲解了,这篇文章的重点主要是讲述一下RN中的Flex布局. CS ...

  3. 关于 devbridge

    目前据我所知最好用的 autocomplete 插件就是 jquery-ui 的 autocomplete 以及 devbridge 的 autocomplete 插件. 我最终选择了 devbrid ...

  4. MySQL笔记(二)之数据检索常用关键字

    SELECT 用于数据的选择 语法: SELECT 列 FROM 表; #从表中选择某些列,也可以是*,代表全部列 DISTINCT 当某些列包含重复值的时候,DISTINCT用于过滤掉重复值,使重复 ...

  5. luoguP4206 [NOI2005]聪聪与可可 期望概率DP

    首先,分析一下这个猫和鼠 猫每局都可以追老鼠一步或者两步,但是除了最后的一步,肯定走两步快些.... 既然猫走的步数总是比老鼠多,那么它们的距离在逐渐缩小(如果这题只能走一步反而不能做了...) 猫不 ...

  6. 工作中用到的git命令

    1.git stash 将本地的修改藏匿,不进行commit也可切换分支 2.git stash apply 将之前藏匿的修改恢复出来 3.git cherry-pick commitId git在当 ...

  7. hihocoder编程收割赛20

    hihocoder编程收割赛20 hihocoder1542 : 无根数变有根树 hihocoder1542 思路: 树的遍历 ac代码: // hihocompete20_01.cpp : 定义控制 ...

  8. js实现大转盘抽奖游戏实例

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  9. IDA64 Fatal error before kernel init

    http://www.tuicool.com/articles/7FZVZna 第一次看到这个错误还以为是修改文件导致的,但是觉得又不大像,因为在Win7底下是完全正常的.搜索了一下才发现是由于插件导 ...

  10. 面试题1:如何实现C++单例模式?

    1. 软件领域中的设计模式为开发人员提供了一种使用专家设计经验的有效途径.设计模式中运用了面向对象编程语言的重要特性:封装.继承.多态.真正领悟设计模式的精髓是可能一个漫长的过程,需要大量实践经验的积 ...