开发者社区> 问答> 正文

java 将图片压缩为指定宽度(高度自动割碎宽度等比例变化)如何实现? 400 报错

java 将图片压缩为指定宽度(高度自动割碎宽度等比例变化)如何实现? 400 报错

按照我的想法,无论针对多少张宽度和高度不一致的图片,最终处理后,会形成宽度都相同,高度随宽度自动变化的效果,但是不能裁剪,在网上查了很多资料,都没有我想要的实现方式,求大神支招,不胜感激。

 

示例:

有两张图片,大小为 400*800和600*1800,按照上述要求将宽度固定为200,则处理后的两张图片分别为200*400和200*600。

展开
收起
爱吃鱼的程序员 2020-06-04 11:54:16 968 0
1 条回答
写回答
取消 提交回答
  • https://developer.aliyun.com/profile/5yerqm5bn5yqg?spm=a2c6h.12873639.0.0.6eae304abcjaIB

    google有个插件超简单就能实现######

    关键在于你如果强压,整个图片就彻底变形了。

    如果要剪裁,那这个判断咋判断?400*800变成200*200,800的部分要减去一半,减哪里?非人工目前仍然难以判断。

    还有一个办法就是加黑边。400*800先等比例压缩到100*200,然后加黑边。补成200*200

    ######

    图片服务器如果用的阿里的oss,阿里就提供了对图片的等比例缩放功能

    ######
    /**
     * scale image
     * 
     * @param sbi image to scale
     * @param imageType type of image
     * @param dWidth width of destination image
     * @param dHeight height of destination image
     * @param fWidth x-factor for transformation / scaling
     * @param fHeight y-factor for transformation / scaling
     * @return scaled image
     */
    public static BufferedImage scale(BufferedImage sbi, int imageType, int dWidth, int dHeight, double fWidth, double fHeight) {
        BufferedImage dbi = null;
        if(sbi != null) {
            dbi = new BufferedImage(dWidth, dHeight, imageType);
            Graphics2D g = dbi.createGraphics();
            AffineTransform at = AffineTransform.getScaleInstance(fWidth, fHeight);
            g.drawRenderedImage(sbi, at);
        }
        return dbi;
    }

    高度=200/原宽度*原高度

    ######

    可以了解一下: https://github.com/liuyueyi/quick-media

    ######

    要按比例缩放,首先你得知道比例,比例就是宽高比(高除以宽)

    BufferedImage bufferedImage = ImageIO.read(new File(input));
    float imageScaler = (float) bufferedImage.getHeight() / (float) bufferedImage.getWidth();

    知道宽高比后,将新宽度乘以比例,就得出新高度了。

    int newWidth = 200;
    float newHeight = newWidth * imageScaler;

    最后调用BufferedImage的getScaledInstance方法就可以得到一个缩放的图片实例

    BufferedImage sacledImage = bufferedImage.getScaledInstance(newWidth, (int) newHeight, java.awt.Image.SCALE_SMOOTH);

    如果对你有用,请采纳

    ######
    1. 从网上找到两张尺寸不同的影像文档;北京火车站(1090 x 697 pixels) 和 北京北海公园(447 x 669 pixels)。
    2. 使用构造方法,将数据下载成 Image 数组 img。
    3. MediaTracker 类是一个跟踪多种媒体对象状态的实用工具类,目前仅支持图像。
    4. 最终,将两幅图片按原来的宽高比,都画成 宽 400 pixels 的相片。

    输出和代码如下:

    import java.net.*;
    import java.awt.*;
    import javax.swing.*;
    import java.awt.image.ImageObserver;
    
    public class Test1 extends JFrame {
    	final int N=2;
    	Image img[] = new Image[N];
    	String data[]={
    "http://img.mp.itc.cn/upload/20161115/d15c330e762142889b6c7b936b9a167d_th.jpeg", //北京火车站
    "http://img.pconline.com.cn/images/upload/upc/tx/itbbs/1510/11/c30/13809065_1444552352198_mthumb.jpg"};
    	
    	public Test1(){
    	super("将2个不同尺寸的影像都画成 400 pixels 宽");
    	setVisible(true);
    	setSize(820,620);
    	setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    	MediaTracker mt= new MediaTracker(this);
    	img= new Image[N];
    	try{ //下载影像数据
    	for (int i=0; i<N;i++){
    	img[i]=Toolkit.getDefaultToolkit().getImage(new URL(data[i]));
    	mt.addImage(img[i],i);
    	}
    	}catch(MalformedURLException e){};
    	
    	try{ //等待影像数据下载完毕
    	mt.waitForAll();
    	}catch(InterruptedException e){}	
      }
      
    /* 参数说明:
     *	g 画笔,i for循环体的控制变量,
     *	width 画成的影像的统一宽度,img 影像对象数组, 
     * 	ob 影像观察者。 
    */
      private void scaledDraw(Graphics g, int i, int width, Image[] img, ImageObserver ob){
      	double ratio = (double)img[i].getHeight(ob)/img[i].getWidth(ob);
    	g.drawImage(img[i], i*width,0,width, (int)(width*ratio),ob);	
      }
      
      public void paint(Graphics g){
    	super.paint(g);
    	for (int i=0;i<N;i++)
    	scaledDraw(g,i,400, img, this);
      }	
      
      public static void main(String args[]){
      	new Test1();
      }	
    }

    将代码稍加改动,就可将网上 6 幅图片按各自的宽高比,一律画成 宽 200 pixels 的相片。注意:JFrame 的标题栏大约占据 35 像素的高度。

    import java.net.*;
    import java.awt.*;
    import javax.swing.*;
    import java.awt.image.ImageObserver;
    
    public class Test extends JFrame {
    	final int N=6;
    	Image img[] = new Image[N];
    	String data[]={
    "http://img1.cache.netease.com/catchpic/D/DD/DD0FBE011074E8416B047F9872ED0510.jpg", 
    "http://i2.sinaimg.cn/ent/v/p/2009-07-31/U2519P28T3D2632036F346DT20090731003121.jpg",
    "http://att2.citysbs.com/hangzhou/sns01/forum/2011/08/02-15/middle_20110802_be197d4095c29cb8b3b0zAgTlytfPTWV.jpg",
    "http://www.cnnb.com.cn/pic/0/00/91/02/910211_876589.jpg",
    "http://photocdn.sohu.com/20120627/Img346622996.jpg",
    "http://www.xgsy188.com/uploadfile/201311521253148455.jpg"};
    	
    	public Test(){
    	super("将6个不同尺寸的宋丹丹影像都画成 200 pixels 宽");
    	setVisible(true);
    	setSize(1210,350);
    	setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    	MediaTracker mt= new MediaTracker(this);
    	img= new Image[N];
    	try{ //下载影像数据
    	for (int i=0; i<N;i++){
    	img[i]=Toolkit.getDefaultToolkit().getImage(new URL(data[i]));
    	mt.addImage(img[i],i);
    	}
    	}catch(MalformedURLException e){};
    	
    	try{ //等待影像数据下载完毕
    	mt.waitForAll();
    	}catch(InterruptedException e){}	
      }
      
    /* 参数说明:
     *	g 画笔,i for循环体的控制变量,
     *	width 画成的影像的统一宽度,img 影像对象数组, 
     * 	ob 影像观察者。 
    */
      private void scaledDraw(Graphics g, int i, int width, Image[] img, ImageObserver ob){
      	double ratio = (double)img[i].getHeight(ob)/img[i].getWidth(ob);
      	// 注意:JFrame 的标题栏大约占据 35 像素的高度
    	g.drawImage(img[i], i*width,35,width, (int)(width*ratio),ob);
      }
      
      public void paint(Graphics g){
    	super.paint(g);
    	for (int i=0;i<N;i++)
    	scaledDraw(g,i,200, img, this);
      }	
      
      public static void main(String args[]){
      	new Test();
      }	
    }

     

    ######看看thumbnailator吧,一行代码搞定尺寸等比例压缩。
    2020-06-04 16:48:30
    赞同 展开评论 打赏
问答分类:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
Spring Cloud Alibaba - 重新定义 Java Cloud-Native 立即下载
The Reactive Cloud Native Arch 立即下载
JAVA开发手册1.5.0 立即下载