문제

Java (Spring, Hibernate/JPA, Struts2)로 작성된 웹 응용 프로그램이 있으며 사용자가 이미지를 업로드하고 파일 시스템에 저장할 수 있습니다. 해당 이미지를 사이트에 표시하기 위해 일관된 크기가되도록 스케일링하고 싶습니다. 어떤 라이브러리 또는 내장 기능이 최상의 결과를 제공합니까? 내 결정을 내리는 데 다음 기준을 고려할 것입니다 (이 순서로).

  • 무료/오픈 소스 (필수)
  • 구현하기 쉽습니다
  • 결과의 품질
  • 성능
  • 실행 파일의 크기
도움이 되었습니까?

해결책

살펴보십시오 Java 이미지 I/O API 이미지를 읽고 쓰기. 그런 다음 사용하십시오 아파니 트랜스 폼 크기를 조정합니다.

또한, 여기에 있습니다 java.awt.image를 사용한 완전한 예.

다른 팁

나는 정말로주는 것이 좋습니다 imgscalr 외모.

호스팅 된 Apache 2 라이센스에 따라 릴리스됩니다. github, 이미 소수의 웹 애플리케이션에 배치되었으며 매우 간단하지만 과대 평가 된 API, 스케일 작동 또는 끔찍한 결과 후 갑자기 "검은 색"이미지를 얻기 시작한 경우에만 주목할 만하면 투명하게 JDK에서 약 2 개의 주요 이미지 버그가 작동하는 코드가 있습니다. Java에서는 Maven과 지퍼를 통해 제공되며 단일 클래스입니다.

기본 사용은 다음과 같습니다.

BufferedImage img = ImageIO.read(...); // load image
BufferedImage scaledImg = Scalr.resize(img, 320);

이것은 도서관이 품질을 가장 잘 추측하고 이미지 비율을 존중하며 320x320 경계 박스 내에서 결과를 맞추는 가장 간단한 호출입니다. 경계 상자는 이미지 비율이 영예 롭기 때문에 사용 된 최대 w/h입니다. 결과 이미지는 여전히 320x200을 존중할 것입니다.

자동 모드를 무시하고 강제로 가장 잘 보이는 결과를 제공하고 결과에 매우 온화한 안티 알리아 필터를 적용하므로 더 좋아 보이도록 (특히 썸네일에 적합 함), 해당 호출은 다음과 같습니다.

BufferedImage img = ImageIO.read(...); // load image
BufferedImage scaledImg = Scalr.resize(img, Method.QUALITY, 
                                       150, 100, Scalr.OP_ANTIALIAS);

이것들은 모두 예제이며, API는 광범위하며 초기 사용 사례에서 매우 전문화 된 모든 것을 다룹니다. 이미지에 적용하기 위해 자신의 BufferedImageops를 전달할 수도 있습니다 (및 라이브러리는 6 년 BufferedImageop JDK 버그를 자동으로 수정합니다!)

Java의 이미지를 성공적으로 스케일링하는 데는 더 많은 것이 더 많은 것이 있습니다. 예를 들어, 이미지는 항상 가장 잘 지원되는 RGB 또는 ArgB 이미지 유형 중 하나에 이미지를 유지하면서 이미지를 유지합니다. 표지 아래에서 Java2D 이미지 처리 파이프 라인은 이미지 작업에 사용되는 이미지 유형이 제대로 지원되지 않으면 열등한 소프트웨어 파이프 라인으로 돌아갑니다.

많은 두통처럼 들린다면, 그것은 일종의 것입니다 ... 그래서 제가 도서관을 썼고 공개 공급원이기 때문에 사람들은 단지 이미지를 크기를 조정하고 걱정할 필요없이 그들의 삶을 계속 진행할 수있었습니다.

도움이되기를 바랍니다.

또한 조사하십시오 자바 이미지 스케일링 도서관. Imageio가 더 나은 품질의 이미지를 만들었습니다.

나는 이것이 아주 오래된 질문이라는 것을 알고 있지만 표준 Java API를 사용하여 이것에 대한 내 솔루션을 얻었습니다.

import java.awt.*;
import java.awt.event.*;
import javax.imageio.*
import java.awt.image.*;

BufferedImage im, bi, bi2;
Graphics2D gfx;
int imWidth, imHeight, dstWidth, dstHeight;
int DESIRED_WIDTH = 500, DESIRED_HEIGHT = 500;

im = ImageIO.read(new File(filePath));
imWidth = im.getWidth(null);
imHeight = im.getHeight(null);

dstWidth = DESIRED_WIDTH;
dstHeight = (dstWidth * imHeight) / imWidth;

bi = new BufferedImage(dstWidth, dstHeight, im.getType());

gfx = bi.createGraphics();
gfx.drawImage(im, 0, 0, dstWidth, dstHeight, 0, 0, imWidth, imHeight, null);

bi2 = new BufferedImage(DESIRED_WIDTH, DESIRED_HEIGHT, im.getType());
gfx = bi2.createGraphics();

gfx.drawImage(bi, 0, 0, DESIRED_WIDTH, DESIRED_HEIGHT, null);

ImageIO.write(bi2, "jpg", new File(filePath));

나는 그것이 개선되고 적응 될 수 있다고 확신합니다.

이미지 편집을위한 가장 좋은 도구는입니다 Imagemagick 그리고 그것은 오픈 소스입니다.

Java 언어에는 두 가지 인터페이스가 있습니다.

Jmagick imagemagick에 JNI 인터페이스를 사용합니다

그리고

Im4java Imagemagick의 명령 줄 인터페이스는 무엇입니까?

표준 Java 1.6과 비교하여 IMGSCALR을 시도했는데 더 좋다고 말할 수는 없습니다.

내가 시도한 것은

BufferedImage bufferedScaled = Scalr.resize(sourceImage, Method.QUALITY, 8000, height);

그리고

  Image scaled = sourceImage.getScaledInstance(-1, height, Image.SCALE_SMOOTH);
  BufferedImage bufferedScaled = new BufferedImage(scaled.getWidth(null),  scaled.getHeight(null), BufferedImage.TYPE_INT_RGB);
  bufferedScaled.getGraphics().drawImage(scaled, 0, 0, null);

My Eye에 의한 5 분의 테스트는 두 번째 (순수 Java 1.6)가 더 나은 결과를 얻는다는 인상을 받았습니다.

더 빠른 것으로 나타났습니다.

public static BufferedImage getScaledInstance(final BufferedImage img, final int targetWidth, final int targetHeight,
                                              final Object hint) {
    final int type = BufferedImage.TYPE_INT_RGB;
    int drawHeight = targetHeight;
    int drawWidth = targetWidth;
    final int imageWidth = img.getWidth();
    final int imageHeight = img.getHeight();
    if ((imageWidth <= targetWidth) && (imageHeight <= targetHeight)) {
        logger.info("Image " + imageWidth + "/" + imageHeight + " within desired scale");
        return img;
    }
    final double sar = ((double) imageWidth) / ((double) imageHeight);
    if (sar != 0) {
        final double tar = ((double) targetWidth) / ((double) targetHeight);
        if ((Math.abs(tar - sar) > .001) && (tar != 0)) {
            final boolean isSoureWider = sar > (targetWidth / targetHeight);
            if (isSoureWider) {
                drawHeight = (int) (targetWidth / sar);
            }
            else {
                drawWidth = (int) (targetHeight * sar);
            }
        }
    }
    logger.info("Scaling image from " + imageWidth + "/" + imageHeight + " to " + drawWidth + "/" + drawHeight);
    final BufferedImage result = new BufferedImage(drawWidth, drawHeight, type);
    try {
        final Graphics2D g2 = result.createGraphics();
        try {
            if (hint != null) {
                g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
            }
            g2.drawImage(img, 0, 0, drawWidth, drawHeight, null);
        }
        finally {
            g2.dispose();
        }
        return result;
    }
    finally {
        result.flush();
    }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top