需求:
有一張位置大小的圖片,現在需要根據這張原圖得到指定尺寸的圖片,且得到的圖片要符合原先圖片的比例,就是在原圖的基礎上等比例縮放得到圖片后,在進行剪裁,這樣保證得到的圖片是原圖的一部分,而不是將原圖拉伸或着是壓縮到指定的尺寸,這樣的圖片就會嚴重的失真,且不協調。
例如:
一張原圖為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);