爪哇图像调整大小,保持纵横比爪哇图像调整大小,保持纵横比(Java image resize, ma

2019-05-13 14:06发布

我有我调整图像大小:

if((width != null) || (height != null))
{
    try{
        // scale image on disk
        BufferedImage originalImage = ImageIO.read(file);
        int type = originalImage.getType() == 0? BufferedImage.TYPE_INT_ARGB
                                               : originalImage.getType();

        BufferedImage resizeImageJpg = resizeImage(originalImage, type, 200, 200);
        ImageIO.write(resizeImageJpg, "jpg", file); 

       } catch(IOException e) {
           System.out.println(e.getMessage());
       }
}

这是我如何调整图像大小:

private static BufferedImage resizeImage(BufferedImage originalImage, int type,
                                         Integer img_width, Integer img_height)
{
    BufferedImage resizedImage = new BufferedImage(img_width, img_height, type);
    Graphics2D g = resizedImage.createGraphics();
    g.drawImage(originalImage, 0, 0, img_width, img_height, null);
    g.dispose();

    return resizedImage;
}

现在的问题是,我还需要保持纵横比。 也就是说,我需要新的200/200图像包含缩放的新形象。 事情是这样的:

我尝试了一些东西,但如预期,他们没有发挥出来。 任何帮助表示赞赏。 非常感谢。

Answer 1:

开始了:

Dimension imgSize = new Dimension(500, 100);
Dimension boundary = new Dimension(200, 200);

函数返回取决于边界上的新的大小

public static Dimension getScaledDimension(Dimension imgSize, Dimension boundary) {

    int original_width = imgSize.width;
    int original_height = imgSize.height;
    int bound_width = boundary.width;
    int bound_height = boundary.height;
    int new_width = original_width;
    int new_height = original_height;

    // first check if we need to scale width
    if (original_width > bound_width) {
        //scale width to fit
        new_width = bound_width;
        //scale height to maintain aspect ratio
        new_height = (new_width * original_height) / original_width;
    }

    // then check if we need to scale even with the new height
    if (new_height > bound_height) {
        //scale height to fit instead
        new_height = bound_height;
        //scale width to maintain aspect ratio
        new_width = (new_height * original_width) / original_height;
    }

    return new Dimension(new_width, new_height);
}

在任何情况下也需要影像缩放代码, 这里是一个体面的解决办法 。

如果你不确定上述方案有不同的方式来达到同样的效果。



Answer 2:

你会想看看Image.getScaledInstance()这个答案,更多: 如何提高g.drawImage的),用于调整图像大小的性能(方法



Answer 3:

译自这里 :

Dimension getScaledDimension(Dimension imageSize, Dimension boundary) {
    double widthRatio = boundary.getWidth() / imageSize.getWidth();
    double heightRatio = boundary.getHeight() / imageSize.getHeight();
    double ratio = Math.min(widthRatio, heightRatio);

    return new Dimension((int) (imageSize.width * ratio), (int) (imageSize.height * ratio));
}

您还可以使用imgscalr来调整,同时保持纵横比的图像:

BufferedImage resizeMe = ImageIO.read(new File("orig.jpg"));
Dimension newMaxSize = new Dimension(255, 255);
BufferedImage resizedImg = Scalr.resize(resizeMe, Method.QUALITY, newMaxSize.width, newMaxSize.height);


Answer 4:

试试这个

float rateX =  (float)jpDisplayImagen.getWidth()/(float)img.getWidth();
float rateY = (float)jpDisplayImagen.getHeight()/(float)img.getHeight();
if (rateX>rateY){
    int W=(int)(img.getWidth()*rateY);
    int H=(int)(img.getHeight()*rateY);
    jpDisplayImagen.getGraphics().drawImage(img, 0, 0,W,H, null);
}
else{
    int W=(int)(img.getWidth()*rateX);
    int H=(int)(img.getHeight()*rateX);
    jpDisplayImagen.getGraphics().drawImage(img, 0, 0,W,H, null);
}


Answer 5:

public class ImageTransformation {

public static final String PNG = "png";

public static byte[] resize(FileItem fileItem, int width, int height) {

    try {
        ResampleOp resampleOp = new ResampleOp(width, height);
        BufferedImage scaledImage = resampleOp.filter(ImageIO.read(fileItem.getInputStream()), null);

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ImageIO.write(scaledImage, PNG, baos);

        return baos.toByteArray();
    } catch (Exception ex) {
        throw new MapsException("An error occured during image resizing.", ex);
    }

}

public static byte[] resizeAdjustMax(FileItem fileItem, int maxWidth, int maxHeight) {

    try {
        BufferedInputStream bis = new BufferedInputStream(fileItem.getInputStream());  
        BufferedImage bufimg = ImageIO.read(bis);   

        //check size of image 
        int img_width = bufimg.getWidth();
        int img_height = bufimg.getHeight();
        if(img_width > maxWidth || img_height > maxHeight) {
            float factx = (float) img_width / maxWidth;
            float facty = (float) img_height / maxHeight;
            float fact = (factx>facty) ? factx : facty;
            img_width = (int) ((int) img_width / fact);
            img_height = (int) ((int) img_height / fact);
        }

        return resize(fileItem,img_width, img_height);

    } catch (Exception ex) {
        throw new MapsException("An error occured during image resizing.", ex);
    }

}

}



Answer 6:

这是我的解决方案:

/*
Change dimension of Image
*/
public static Image resizeImage(Image image, int scaledWidth, int scaledHeight, boolean preserveRatio) {  

    if (preserveRatio) { 
        double imageHeight = image.getHeight();
        double imageWidth = image.getWidth();

        if (imageHeight/scaledHeight > imageWidth/scaledWidth) {
            scaledWidth = (int) (scaledHeight * imageWidth / imageHeight);
        } else {
            scaledHeight = (int) (scaledWidth * imageHeight / imageWidth);
        }        
    }                   
    BufferedImage inputBufImage = SwingFXUtils.fromFXImage(image, null);     
    // creates output image
    BufferedImage outputBufImage = new BufferedImage(scaledWidth, scaledHeight, inputBufImage.getType());       
    // scales the input image to the output image
    Graphics2D g2d = outputBufImage.createGraphics();
    g2d.drawImage(inputBufImage, 0, 0, scaledWidth, scaledHeight, null);
    g2d.dispose();      
    return SwingFXUtils.toFXImage(outputBufImage, null);
}


Answer 7:

所有其他的答案显示如何计算在新的图像宽度或反之亦然,以及如何调整使用Java图像API的图像的功能,新的图像高度。 对于谁是寻找一个简单的解决方案的人,我建议任何Java图像处理框架,可以在单行做到这一点。

下面的使用为例张建东框架 :

// 300 is the new width. The height is calculated to maintain aspect.
scale(image.clone(), image, 300);

必要的进口:

import static marvin.MarvinPluginCollection.*


Answer 8:

加载图像:

BufferedImage bufferedImage = ImageIO.read(file);   

调整它:

private BufferedImage resizeAndCrop(BufferedImage bufferedImage, Integer width, Integer height) {

    Mode mode = (double) width / (double) height >= (double) bufferedImage.getWidth() / (double) bufferedImage.getHeight() ? Scalr.Mode.FIT_TO_WIDTH
            : Scalr.Mode.FIT_TO_HEIGHT;

    bufferedImage = Scalr.resize(bufferedImage, Scalr.Method.ULTRA_QUALITY, mode, width, height);

    int x = 0;
    int y = 0;

    if (mode == Scalr.Mode.FIT_TO_WIDTH) {
        y = (bufferedImage.getHeight() - height) / 2;
    } else if (mode == Scalr.Mode.FIT_TO_HEIGHT) {
        x = (bufferedImage.getWidth() - width) / 2;
    }

    bufferedImage = Scalr.crop(bufferedImage, x, y, width, height);

    return bufferedImage;
}

使用Scalr库:

<dependency>
    <groupId>org.imgscalr</groupId>
    <artifactId>imgscalr-lib</artifactId>
    <version>4.2</version>
</dependency>


Answer 9:

我已经找到了选择的答案有一个与升频的问题,所以我做了(还)另一版本(我已经测试):

public static Point scaleFit(Point src, Point bounds) {
  int newWidth = src.x;
  int newHeight = src.y;
  double boundsAspectRatio = bounds.y / (double) bounds.x;
  double srcAspectRatio = src.y / (double) src.x;

  // first check if we need to scale width
  if (boundsAspectRatio < srcAspectRatio) {
    // scale width to fit
    newWidth = bounds.x;
    //scale height to maintain aspect ratio
    newHeight = (newWidth * src.y) / src.x;
  } else {
    //scale height to fit instead
    newHeight = bounds.y;
    //scale width to maintain aspect ratio
    newWidth = (newHeight * src.x) / src.y;
  }

  return new Point(newWidth, newHeight);
}

写在Android的术语:-)

作为测试:

@Test public void scaleFit() throws Exception {
  final Point displaySize = new Point(1080, 1920);
  assertEquals(displaySize, Util.scaleFit(displaySize, displaySize));
  assertEquals(displaySize, Util.scaleFit(new Point(displaySize.x / 2, displaySize.y / 2), displaySize));
  assertEquals(displaySize, Util.scaleFit(new Point(displaySize.x * 2, displaySize.y * 2), displaySize));
  assertEquals(new Point(displaySize.x, displaySize.y * 2), Util.scaleFit(new Point(displaySize.x / 2, displaySize.y), displaySize));
  assertEquals(new Point(displaySize.x * 2, displaySize.y), Util.scaleFit(new Point(displaySize.x, displaySize.y / 2), displaySize));
  assertEquals(new Point(displaySize.x, displaySize.y * 3 / 2), Util.scaleFit(new Point(displaySize.x / 3, displaySize.y / 2), displaySize));
}


Answer 10:

这里的一个小片的,我写代码,它调整大小以适合的容器中,同时保持图像的原始长宽比的图像。 它发生在作为参数容器的宽度,高度和图像。 你可以修改它以满足您的需求。 它的简单和我的应用程序工作正常。

private Image scaleimage(int wid, int hei, BufferedImage img){
    Image im = img;
    double scale;
    double imw = img.getWidth();
    double imh = img.getHeight();
    if (wid > imw && hei > imh){
        im = img;
    }else if(wid/imw < hei/imh){
        scale = wid/imw;
        im = img.getScaledInstance((int) (scale*imw), (int) (scale*imh), Image.SCALE_SMOOTH);
    }else if (wid/imw > hei/imh){
        scale = hei/imh;
        im = img.getScaledInstance((int) (scale*imw), (int) (scale*imh), Image.SCALE_SMOOTH);
    }else if (wid/imw == hei/imh){
        scale = wid/imw;
        im = img.getScaledInstance((int) (scale*imw), (int) (scale*imh), Image.SCALE_SMOOTH);
    } 
    return im;
}


Answer 11:

只是多了一个块添加到奥兹的代码,这样的事情是这样的:

public static Dimension getScaledDimension(Dimension imgSize,Dimension boundary) {

    int original_width = imgSize.width;
    int original_height = imgSize.height;
    int bound_width = boundary.width;
    int bound_height = boundary.height;
    int new_width = original_width;
    int new_height = original_height;

    // first check if we need to scale width
    if (original_width > bound_width) {
        //scale width to fit
        new_width = bound_width;
        //scale height to maintain aspect ratio
        new_height = (new_width * original_height) / original_width;
    }

    // then check if we need to scale even with the new height
    if (new_height > bound_height) {
        //scale height to fit instead
        new_height = bound_height;
        //scale width to maintain aspect ratio
        new_width = (new_height * original_width) / original_height;
    }
    // upscale if original is smaller
    if (original_width < bound_width) {
        //scale width to fit
        new_width = bound_width;
        //scale height to maintain aspect ratio
        new_height = (new_width * original_height) / original_width;
    }

    return new Dimension(new_width, new_height);
}


文章来源: Java image resize, maintain aspect ratio