Изменить размер изображения - PullRequest
39 голосов
/ 23 февраля 2012

Я пытаюсь изменить размер буферизованного изображения.Я могу сохранить его и показать на jframe без проблем, но я не могу изменить его размер.Любые советы о том, как я могу изменить это, чтобы заставить его работать и показывать изображение в виде файла 200 * 200, были бы великолепны

Ответы [ 7 ]

49 голосов
/ 23 февраля 2012

Обновленный ответ

Не могу вспомнить, почему мой оригинальный ответ сработал, но, протестировав его в отдельной среде, я согласен, оригинальный принятый ответ не работает (почему я сказал, что сделал, я тоже не могу вспомнить). Это, с другой стороны, сработало:

public static BufferedImage resize(BufferedImage img, int newW, int newH) { 
    Image tmp = img.getScaledInstance(newW, newH, Image.SCALE_SMOOTH);
    BufferedImage dimg = new BufferedImage(newW, newH, BufferedImage.TYPE_INT_ARGB);

    Graphics2D g2d = dimg.createGraphics();
    g2d.drawImage(tmp, 0, 0, null);
    g2d.dispose();

    return dimg;
}  
19 голосов
/ 23 февраля 2012

Если все, что требуется, это изменить размер BufferedImage в методе resize, то библиотека Thumbnailator может сделать это довольно легко:

public static BufferedImage resize(BufferedImage img, int newW, int newH) {
  return Thumbnails.of(img).size(newW, newH).asBufferedImage();
}

Приведенный выше код изменит размер img для соответствия размерам newW и newH при сохранении соотношения сторон исходного изображения.

Если поддержание соотношения сторон не требуется и требуется изменение размера до заданных размеров, вместо метода size можно использовать метод forceSize:

public static BufferedImage resize(BufferedImage img, int newW, int newH) {
  return Thumbnails.of(img).forceSize(newW, newH).asBufferedImage();
}

Использование метода Image.getScaledInstance не гарантирует сохранения соотношения сторон исходного изображения для изображения с измененным размером, и, кроме того, оно обычно очень медленное.

Thumbnailator использует метод постепенного изменения размера изображения, который может быть в в несколько раз быстрее, чем Image.getScaledInstance при достижении качества изображения, которое обычно сопоставимо.

Отказ от ответственности: я хранитель этой библиотеки.

3 голосов
/ 06 декабря 2013

попробуйте библиотеку imgscalr.Лучшая библиотека, которую я нашел - очень быстро, качественно и просто в использовании

BufferedImage thumbnail = Scalr.resize(image, 150);

http://www.thebuzzmedia.com/software/imgscalr-java-image-scaling-library/

Лицензия Apache 2

3 голосов
/ 08 ноября 2013

Этот класс изменяется из файла и получает имя формата:

import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageInputStream;
import org.apache.commons.io.IOUtils;

public class ImageResizer {

public static void main(String as[]) throws IOException{

    File f = new File("C:/Users/samsungrob/Desktop/shuttle.jpg");

    byte[] ba = resize(f, 600, 600);

    IOUtils.write(ba, new FileOutputStream( new File("C:/Users/samsungrob/Desktop/shuttle_resized.jpg") ) );

}




public static byte[] resize(File file,
                            int maxWidth, int maxHeight) throws IOException{
    int scaledWidth = 0, scaledHeight = 0;

    BufferedImage img = ImageIO.read((ImageInputStream) file );

    scaledWidth = maxWidth;
    scaledHeight = (int) (img.getHeight() * ( (double) scaledWidth / img.getWidth() ));

    if (scaledHeight> maxHeight) {
        scaledHeight = maxHeight;
        scaledWidth= (int) (img.getWidth() * ( (double) scaledHeight/ img.getHeight() ));

        if (scaledWidth > maxWidth) {
            scaledWidth = maxWidth;
            scaledHeight = maxHeight;
        }
    }

    Image resized =  img.getScaledInstance( scaledWidth, scaledHeight, Image.SCALE_SMOOTH);

    BufferedImage buffered = new BufferedImage(scaledWidth, scaledHeight, Image.SCALE_REPLICATE);

    buffered.getGraphics().drawImage(resized, 0, 0 , null);

    String formatName = getFormatName( file ) ;

    ByteArrayOutputStream out = new ByteArrayOutputStream();

    ImageIO.write(buffered,
            formatName,
            out);

    return out.toByteArray();
}


private static String getFormatName(ImageInputStream iis) {
    try { 

        // Find all image readers that recognize the image format
        Iterator iter = ImageIO.getImageReaders(iis);
        if (!iter.hasNext()) {
            // No readers found
            return null;
        }

        // Use the first reader
        ImageReader reader = (ImageReader)iter.next();

        // Close stream
        iis.close();

        // Return the format name
        return reader.getFormatName();
    } catch (IOException e) {
    }

    return null;
}

private static String getFormatName(File file) throws IOException {
    return getFormatName( ImageIO.createImageInputStream(file) );
}

private static String getFormatName(InputStream is) throws IOException {
    return getFormatName( ImageIO.createImageInputStream(is) );
}

}

2 голосов
/ 27 июня 2017

Вот код, который я использовал для изменения размера буферизованных изображений, без излишеств, довольно быстро:

public static BufferedImage scale(BufferedImage src, int w, int h)
{
    BufferedImage img = 
            new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
    int x, y;
    int ww = src.getWidth();
    int hh = src.getHeight();
    int[] ys = new int[h];
    for (y = 0; y < h; y++)
        ys[y] = y * hh / h;
    for (x = 0; x < w; x++) {
        int newX = x * ww / w;
        for (y = 0; y < h; y++) {
            int col = src.getRGB(newX, ys[y]);
            img.setRGB(x, y, col);
        }
    }
    return img;
}
1 голос
/ 27 ноября 2018

Это сокращенная версия того, что на самом деле происходит в imgscalr, если вы просто хотите использовать «сбалансированное» сглаживание:

/**
 * Takes a BufferedImage and resizes it according to the provided targetSize
 *
 * @param src the source BufferedImage
 * @param targetSize maximum height (if portrait) or width (if landscape)
 * @return a resized version of the provided BufferedImage
 */
private BufferedImage resize(BufferedImage src, int targetSize) {
    if (targetSize <= 0) {
        return src; //this can't be resized
    }
    int targetWidth = targetSize;
    int targetHeight = targetSize;
    float ratio = ((float) src.getHeight() / (float) src.getWidth());
    if (ratio <= 1) { //square or landscape-oriented image
        targetHeight = (int) Math.ceil((float) targetWidth * ratio);
    } else { //portrait image
        targetWidth = Math.round((float) targetHeight / ratio);
    }
    BufferedImage bi = new BufferedImage(targetWidth, targetHeight, src.getTransparency() == Transparency.OPAQUE ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB);
    Graphics2D g2d = bi.createGraphics();
    g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); //produces a balanced resizing (fast and decent quality)
    g2d.drawImage(src, 0, 0, targetWidth, targetHeight, null);
    g2d.dispose();
    return bi;
}
0 голосов
/ 22 сентября 2014

Проверьте это, это помогает:

BufferedImage bImage = ImageIO.read(new File(C:\image.jpg);

BufferedImage thumbnail = Scalr.resize(bImage,  Scalr.Method.SPEED, Scalr.Mode.FIT_TO_WIDTH,
                                       750, 150, Scalr.OP_ANTIALIAS);
...