IT박스

Java를 사용하여 이미지 크기를 조정하는 방법

itboxs 2020. 7. 9. 19:31
반응형

Java를 사용하여 이미지 크기를 조정하는 방법


PNG, JPEG 및 GIF 파일의 크기를 조정해야합니다. Java를 사용하여이 작업을 수행하려면 어떻게해야합니까?


이미지를로드 한 후에 시도해 볼 수 있습니다 :

BufferedImage createResizedCopy(Image originalImage, 
            int scaledWidth, int scaledHeight, 
            boolean preserveAlpha)
    {
        System.out.println("resizing...");
        int imageType = preserveAlpha ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
        BufferedImage scaledBI = new BufferedImage(scaledWidth, scaledHeight, imageType);
        Graphics2D g = scaledBI.createGraphics();
        if (preserveAlpha) {
            g.setComposite(AlphaComposite.Src);
        }
        g.drawImage(originalImage, 0, 0, scaledWidth, scaledHeight, null); 
        g.dispose();
        return scaledBI;
    }

FWIW 방금 imgscalr ( Maven central에서 사용 가능) 이라는 Java 용 간단한 이미지 스케일링 라이브러리 (GitHub에서 호스팅되는 Apache 2)를 출시했습니다 .

이 라이브러리는 이미지 스케일링에 대한 몇 가지 다른 접근 방식을 구현하며 (몇 가지 사소한 개선 사항이있는 Chris Campbell의 증분 방식 포함) 요청하면 가장 적합한 방식을 선택하거나 가장 빠르거나 최상의 모습을 제공합니다 ( 요청하십시오).

사용법은 매우 간단하고 정적 메소드입니다. 가장 간단한 사용 사례는 다음과 같습니다.

BufferedImage scaledImage = Scalr.resize(myImage, 200);

모든 작업은 이미지의 원래 비율을 유지하므로이 경우 이미지 크기를 200 픽셀과 200 픽셀의 범위 내에서 이미지 크기를 조정하도록 imgscalr에 요청하면 기본적으로 가장 오래되고 가장 빠른 방법을 자동으로 선택합니다. 지정되지 않았습니다.

나는 처음에는 이것이 자기 진흥처럼 보인다는 것을 알고 있지만, 나는 똑같은 주제를 인터넷 검색하는 데 상당한 시간을 보냈고 다른 결과 / 접근법 / 생각 / 제안을 계속해서 앉아서 앉아서 결정했습니다. 이미지가 있고 가능한 한 빨리보기 좋거나보기 좋은 이미지를 원한다면 80-85 %의 사용 사례를 처리하는 간단한 구현입니다. 작은 이미지로 BICUBIC 보간을 사용하여 Graphics.drawImage를 수행해도 여전히 쓰레기처럼 보입니다.)


ThumbnailatorMIT 라이센스에 따라 유창한 인터페이스를 갖춘 Java 용 오픈 소스 이미지 크기 조정 라이브러리입니다 .

Java로 고품질 썸네일을 만드는 것은 놀라 울 정도로 어려울 수 있으며 결과 코드가 매우 어려울 수 있기 때문에이 라이브러리를 작성했습니다. Thumbnailator를 사용하면 간단한 유창한 API를 사용하여 상당히 복잡한 작업을 표현할 수 있습니다.

간단한 예

간단한 예를 들어, 이미지를 가져 와서 100 x 100으로 크기를 조정하고 (원본 이미지의 가로 세로 비율을 유지) 파일에 저장하면 단일 명령문으로 달성 할 수 있습니다.

Thumbnails.of("path/to/image")
    .size(100, 100)
    .toFile("path/to/thumbnail");

고급 예

Thumbnailator의 다양한 인터페이스를 통해 복잡한 크기 조정 작업을 간편하게 수행 할 수 있습니다.

다음과 같이한다고 가정 해 봅시다.

  1. 디렉토리에서 이미지를 가져와
  2. 원본 이미지의 가로 세로 비율로 100 x 100으로 크기를 조정합니다.
  3. 의 품질 설정을 사용하여 JPEG에 모두 저장하십시오 0.85.
  4. 파일 이름은 처음에 thumbnail.추가 된 원본에서 가져옵니다.

Thumbnailator로 번역하면 다음을 통해 위의 작업을 수행 할 수 있습니다.

Thumbnails.of(new File("path/to/directory").listFiles())
    .size(100, 100)
    .outputFormat("JPEG")
    .outputQuality(0.85)
    .toFiles(Rename.PREFIX_DOT_THUMBNAIL);

이미지 품질 및 속도에 대한 참고 사항

이 라이브러리는 또한 만족스러운 런타임 성능을 보장하면서 고품질 썸네일을 생성하기 위해 Chet Haase 및 Romain Guy의 Filthy Rich Clients 에서 강조된 점진적 이중 선형 스케일링 방법을 사용합니다 .


이를 위해 라이브러리가 필요하지 않습니다. Java 자체로 할 수 있습니다.

Chris Campbell은 이미지 스케일링에 대해 훌륭하고 자세한 글을 작성했습니다 . 이 기사를 참조 하십시오 .

Chet Haase와 Romain Guy도 그들의 책 Filthy Rich Clients에 상세하고 매우 유용한 이미지 스케일링을 기록했습니다 .


Java Advanced Imaging is now open source, and provides the operations you need.


If you are dealing with large images or want a nice looking result it's not a trivial task in java. Simply doing it via a rescale op via Graphics2D will not create a high quality thumbnail. You can do it using JAI, but it requires more work than you would imagine to get something that looks good and JAI has a nasty habit of blowing our your JVM with OutOfMemory errors.

I suggest using ImageMagick as an external executable if you can get away with it. Its simple to use and it does the job right so that you don't have to.


If, having imagemagick installed on your maschine is an option, I recommend im4java. It is a very thin abstraction layer upon the command line interface, but does its job very well.


The Java API does not provide a standard scaling feature for images and downgrading image quality.

Because of this I tried to use cvResize from JavaCV but it seems to cause problems.

I found a good library for image scaling: simply add the dependency for "java-image-scaling" in your pom.xml.

<dependency>
    <groupId>com.mortennobel</groupId>
    <artifactId>java-image-scaling</artifactId>
    <version>0.8.6</version>
</dependency>

In the maven repository you will get the recent version for this.

Ex. In your java program

ResampleOp resamOp = new ResampleOp(50, 40);
BufferedImage modifiedImage = resamOp.filter(originalBufferedImage, null);

You could try to use GraphicsMagick Image Processing System with im4java as a comand-line interface for Java.

There are a lot of advantages of GraphicsMagick, but one for all:

  • GM is used to process billions of files at the world's largest photo sites (e.g. Flickr and Etsy).

Image Magick has been mentioned. There is a JNI front end project called JMagick. It's not a particularly stable project (and Image Magick itself has been known to change a lot and even break compatibility). That said, we've had good experience using JMagick and a compatible version of Image Magick in a production environment to perform scaling at a high throughput, low latency rate. Speed was substantially better then with an all Java graphics library that we previously tried.

http://www.jmagick.org/index.html


Simply use Burkhard's answer but add this line after creating the graphics:

    g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);

You could also set the value to BICUBIC, it will produce a better quality image but is a more expensive operation. There are other rendering hints you can set but I have found that interpolation produces the most notable effect. Keep in mind if you want to zoom in in a lot, java code most likely will be very slow. I find larger images start to produce lag around 300% zoom even with all rendering hints set to optimize for speed over quality.


You can use Marvin (pure Java image processing framework) for this kind of operation: http://marvinproject.sourceforge.net

Scale plug-in: http://marvinproject.sourceforge.net/en/plugins/scale.html


It turns out that writing a performant scaler is not trivial. I did it once for an open source project: ImageScaler.

In principle 'java.awt.Image#getScaledInstance(int, int, int)' would do the job as well, but there is a nasty bug with this - refer to my link for details.


I have developed a solution with the freely available classes ( AnimatedGifEncoder, GifDecoder, and LWZEncoder) available for handling GIF Animation.
You can download the jgifcode jar and run the GifImageUtil class. Link: http://www.jgifcode.com


you can use following popular product: thumbnailator


If you dont want to import imgScalr like @Riyad Kalla answer above which i tested too works fine, you can do this taken from Peter Walser answer @Peter Walser on another issue though:

 /**
     * utility method to get an icon from the resources of this class
     * @param name the name of the icon
     * @return the icon, or null if the icon wasn't found.
     */
    public Icon getIcon(String name) {
        Icon icon = null;
        URL url = null;
        ImageIcon imgicon = null;
        BufferedImage scaledImage = null;
        try {
            url = getClass().getResource(name);

            icon = new ImageIcon(url);
            if (icon == null) {
                System.out.println("Couldn't find " + url);
            }

            BufferedImage bi = new BufferedImage(
                    icon.getIconWidth(),
                    icon.getIconHeight(),
                    BufferedImage.TYPE_INT_RGB);
            Graphics g = bi.createGraphics();
            // paint the Icon to the BufferedImage.
            icon.paintIcon(null, g, 0,0);
            g.dispose();

            bi = resizeImage(bi,30,30);
            scaledImage = bi;// or replace with this line Scalr.resize(bi, 30,30);
            imgicon = new ImageIcon(scaledImage);

        } catch (Exception e) {
            System.out.println("Couldn't find " + getClass().getName() + "/" + name);
            e.printStackTrace();
        }
        return imgicon;
    }

 public static BufferedImage resizeImage (BufferedImage image, int areaWidth, int areaHeight) {
        float scaleX = (float) areaWidth / image.getWidth();
        float scaleY = (float) areaHeight / image.getHeight();
        float scale = Math.min(scaleX, scaleY);
        int w = Math.round(image.getWidth() * scale);
        int h = Math.round(image.getHeight() * scale);

        int type = image.getTransparency() == Transparency.OPAQUE ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;

        boolean scaleDown = scale < 1;

        if (scaleDown) {
            // multi-pass bilinear div 2
            int currentW = image.getWidth();
            int currentH = image.getHeight();
            BufferedImage resized = image;
            while (currentW > w || currentH > h) {
                currentW = Math.max(w, currentW / 2);
                currentH = Math.max(h, currentH / 2);

                BufferedImage temp = new BufferedImage(currentW, currentH, type);
                Graphics2D g2 = temp.createGraphics();
                g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
                g2.drawImage(resized, 0, 0, currentW, currentH, null);
                g2.dispose();
                resized = temp;
            }
            return resized;
        } else {
            Object hint = scale > 2 ? RenderingHints.VALUE_INTERPOLATION_BICUBIC : RenderingHints.VALUE_INTERPOLATION_BILINEAR;

            BufferedImage resized = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
            Graphics2D g2 = resized.createGraphics();
            g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
            g2.drawImage(image, 0, 0, w, h, null);
            g2.dispose();
            return resized;
        }
    }

참고URL : https://stackoverflow.com/questions/244164/how-can-i-resize-an-image-using-java

반응형