Java를 사용하여 이미지 높이와 폭을 얻는 방법은 무엇입니까?
이미지를 사용하는 것 외에 다른 방법이 있습니까?이미지 높이와 너비를 얻기 위해 IO.read?
스레드를 잠그는 문제가 발생했기 때문입니다.
at com.sun.medialib.codec.jpeg.Decoder.njpeg_decode(Native Method)
at com.sun.medialib.codec.jpeg.Decoder.decode(Decoder.java:87)
at com.sun.media.imageioimpl.plugins.jpeg.CLibJPEGImageReader.decode(CLibJPEGImageReader.java:73)
- locked <0xd96fb668> (a com.sun.media.imageioimpl.plugins.jpeg.CLibJPEGImageReader)
at com.sun.media.imageioimpl.plugins.clib.CLibImageReader.getImage(CLibImageReader.java:320)
- locked <0xd96fb668> (a com.sun.media.imageioimpl.plugins.jpeg.CLibJPEGImageReader)
at com.sun.media.imageioimpl.plugins.clib.CLibImageReader.read(CLibImageReader.java:384)
- locked <0xd96fb668> (a com.sun.media.imageioimpl.plugins.jpeg.CLibJPEGImageReader)
at javax.imageio.ImageIO.read(ImageIO.java:1400)
at javax.imageio.ImageIO.read(ImageIO.java:1322)
이 에러는 Sun 앱 서버에서만 발생하므로 Sun 버그로 의심됩니다.
여기 아주 간단하고 편리한 것이 있습니다.
BufferedImage bimg = ImageIO.read(new File(filename));
int width = bimg.getWidth();
int height = bimg.getHeight();
이것은 IOException을 슬로우하여 조기 종료하는 @Kay에 의한 great post의 개서입니다.
/**
* Gets image dimensions for given file
* @param imgFile image file
* @return dimensions of image
* @throws IOException if the file is not a known image
*/
public static Dimension getImageDimension(File imgFile) throws IOException {
int pos = imgFile.getName().lastIndexOf(".");
if (pos == -1)
throw new IOException("No extension for file: " + imgFile.getAbsolutePath());
String suffix = imgFile.getName().substring(pos + 1);
Iterator<ImageReader> iter = ImageIO.getImageReadersBySuffix(suffix);
while(iter.hasNext()) {
ImageReader reader = iter.next();
try {
ImageInputStream stream = new FileImageInputStream(imgFile);
reader.setInput(stream);
int width = reader.getWidth(reader.getMinIndex());
int height = reader.getHeight(reader.getMinIndex());
return new Dimension(width, height);
} catch (IOException e) {
log.warn("Error reading: " + imgFile.getAbsolutePath(), e);
} finally {
reader.dispose();
}
}
throw new IOException("Not a known image file: " + imgFile.getAbsolutePath());
}
제 의견이 답장으로서 가치가 있다고 여겨질 만큼 제 평판이 높지 않은 것 같습니다.
기재되어 있는 다양한 어프로치를 사용하여 퍼포먼스를 테스트해 보았습니다.많은 요인이 결과에 영향을 미치기 때문에 엄격한 테스트를 하는 것은 어렵습니다.저는 330개의 jpg 파일이 있는 폴더와 330개의 png 파일이 있는 폴더 두 개를 준비했습니다.두 경우 모두 평균 파일 크기는 4Mb였습니다.그리고 각 파일에 대해 getDimension을 호출했습니다.getDimension 메서드의 각 구현과 각 이미지 유형을 개별적으로 테스트했습니다(별도 실행).얻은 실행 시간은 다음과 같습니다(jpg의 경우 첫 번째 번호, png의 경우 두 번째 번호).
1(Apurv) - 101454ms, 84611ms
2(joinJpegs) - 471ms, N/A
3(Andrew Taylor) - 707ms, 68ms
4(Karussell, ImageIcon) - 106655ms, 100898ms
5(user350756) - 2649ms, 68ms
일부 메서드는 치수를 얻기 위해 파일 전체를 로드하는 반면 다른 메서드는 이미지에서 헤더 정보를 읽는 것만으로 로드합니다.애플리케이션 퍼포먼스가 중요한 경우 이 수치가 도움이 될 수 있다고 생각합니다.
이 스레드에 공헌해 주셔서 감사합니다.- 매우 도움이 됩니다.
이미지 크기(더 일반적인)를 읽을 수 있는 다른 방법을 찾았습니다.이미지를 사용할 수 있습니다.ImageReaders와 연계한 IO 클래스.다음은 샘플 코드입니다.
private Dimension getImageDim(final String path) {
Dimension result = null;
String suffix = this.getFileSuffix(path);
Iterator<ImageReader> iter = ImageIO.getImageReadersBySuffix(suffix);
if (iter.hasNext()) {
ImageReader reader = iter.next();
try {
ImageInputStream stream = new FileImageInputStream(new File(path));
reader.setInput(stream);
int width = reader.getWidth(reader.getMinIndex());
int height = reader.getHeight(reader.getMinIndex());
result = new Dimension(width, height);
} catch (IOException e) {
log(e.getMessage());
} finally {
reader.dispose();
}
} else {
log("No reader found for given format: " + suffix));
}
return result;
}
getFileSuffix는 "." 없이 경로 확장을 반환하는 메서드입니다(예: png, jpg 등).구현 예는 다음과 같습니다.
private String getFileSuffix(final String path) {
String result = null;
if (path != null) {
result = "";
if (path.lastIndexOf('.') != -1) {
result = path.substring(path.lastIndexOf('.'));
if (result.startsWith(".")) {
result = result.substring(1);
}
}
}
return result;
}
이 솔루션은 이미지 전체는 읽지 않고 이미지 크기만 파일에서 읽기 때문에 매우 빠릅니다.테스트해 본 결과 이미지와 비교가 되지 않습니다.IO.read 퍼포먼스누군가 이것을 유용하게 여겨주길 바란다.
JPEG 이진 데이터를 파일로 로드하고 JPEG 헤더를 직접 구문 분석할 수 있습니다.찾고 있는 것은 0xFFC0 또는 Start of Frame 헤더입니다.
Start of frame marker (FFC0)
* the first two bytes, the length, after the marker indicate the number of bytes, including the two length bytes, that this header contains
* P -- one byte: sample precision in bits (usually 8, for baseline JPEG)
* Y -- two bytes
* X -- two bytes
* Nf -- one byte: the number of components in the image
o 3 for color baseline JPEG images
o 1 for grayscale baseline JPEG images
* Nf times:
o Component ID -- one byte
o H and V sampling factors -- one byte: H is first four bits and V is second four bits
o Quantization table number-- one byte
The H and V sampling factors dictate the final size of the component they are associated with. For instance, the color space defaults to YCbCr and the H and V sampling factors for each component, Y, Cb, and Cr, default to 2, 1, and 1, respectively (2 for both H and V of the Y component, etc.) in the Jpeg-6a library by the Independent Jpeg Group. While this does mean that the Y component will be twice the size of the other two components--giving it a higher resolution, the lower resolution components are quartered in size during compression in order to achieve this difference. Thus, the Cb and Cr components must be quadrupled in size during decompression.
헤더에 대한 자세한 내용은 위키피디아의 jpeg 엔트리를 확인하거나 위의 정보를 참조하십시오.
Sun 포럼에서 이 게시물에서 얻은 다음 코드와 유사한 방법을 사용했습니다.
import java.awt.Dimension;
import java.io.*;
public class JPEGDim {
public static Dimension getJPEGDimension(File f) throws IOException {
FileInputStream fis = new FileInputStream(f);
// check for SOI marker
if (fis.read() != 255 || fis.read() != 216)
throw new RuntimeException("SOI (Start Of Image) marker 0xff 0xd8 missing");
Dimension d = null;
while (fis.read() == 255) {
int marker = fis.read();
int len = fis.read() << 8 | fis.read();
if (marker == 192) {
fis.skip(1);
int height = fis.read() << 8 | fis.read();
int width = fis.read() << 8 | fis.read();
d = new Dimension(width, height);
break;
}
fis.skip(len - 2);
}
fis.close();
return d;
}
public static void main(String[] args) throws IOException {
System.out.println(getJPEGDimension(new File(args[0])));
}
}
간단한 방법:
BufferedImage readImage = null;
try {
readImage = ImageIO.read(new File(your path);
int h = readImage.getHeight();
int w = readImage.getWidth();
} catch (Exception e) {
readImage = null;
}
툴킷을 사용할 수 있어 이미지가 필요 없음입출력
Image image = Toolkit.getDefaultToolkit().getImage(file.getAbsolutePath());
int width = image.getWidth(null);
int height = image.getHeight(null);
이미지 로드를 처리하지 않으려면 다음을 수행하십시오.
ImageIcon imageIcon = new ImageIcon(file.getAbsolutePath());
int height = imageIcon.getIconHeight();
int width = imageIcon.getIconWidth();
의 문제는 매우IO.read 。이미지 헤더를 읽고 크기를 확인하기만 하면 됩니다. ImageIO.getImageReader완벽한 후보입니다.
다음은 Groovy의 예입니다만, Java에도 같은 것이 적용됩니다.
def stream = ImageIO.createImageInputStream(newByteArrayInputStream(inputStream))
def formatReader = ImageIO.getImageWritersByFormatName(format).next()
def reader = ImageIO.getImageReader(formatReader)
reader.setInput(stream, true)
println "width:reader.getWidth(0) -> height: reader.getHeight(0)"
퍼포먼스는 Simple Image를 사용한 경우와 동일합니다.정보 자바 라이브러리
https://github.com/cbeust/personal/blob/master/src/main/java/com/beust/SimpleImageInfo.java
ImageIO지난 몇 년간 Andrew Taylor의 솔루션은 단연 최고의 타협이라고 생각합니다(빠른: 사용하지 않음).ImageIO#read , 용 ,용 ★★★★★★★★★★★★★★★★★★!
로컬 String)을 수 . 러파 ( /문 / 문문 )를 는, 조금 스러웠습니다.특히, 통상적으로 취득하는 멀티파트/폼 데이터 요구로부터 취득하는 이미지 사이즈를 체크하고 싶은 경우는,InputPart/InputStream s를 받아들일 수 그래서 저는 재빨리 변형을 만들어서File,InputStream ★★★★★★★★★★★★★★★★★」RandomAccessFile해 주세요.ImageIO#createImageInputStream그렇게 하기 위해서.
이런 .Object input는 프라이빗하게 유지되는 것만으로, 필요에 따라서 폴리모픽 메서드를 작성합니다.이 메서드는 이 메서드로 불립니다.,도 수 요.PathPath#toFile() ★★★★★★★★★★★★★★★★★」URLURL#openStream()에: 이 방법을 사용합니다.
private static Dimension getImageDimensions(Object input) throws IOException {
try (ImageInputStream stream = ImageIO.createImageInputStream(input)) { // accepts File, InputStream, RandomAccessFile
if(stream != null) {
IIORegistry iioRegistry = IIORegistry.getDefaultInstance();
Iterator<ImageReaderSpi> iter = iioRegistry.getServiceProviders(ImageReaderSpi.class, true);
while (iter.hasNext()) {
ImageReaderSpi readerSpi = iter.next();
if (readerSpi.canDecodeInput(stream)) {
ImageReader reader = readerSpi.createReaderInstance();
try {
reader.setInput(stream);
int width = reader.getWidth(reader.getMinIndex());
int height = reader.getHeight(reader.getMinIndex());
return new Dimension(width, height);
} finally {
reader.dispose();
}
}
}
throw new IllegalArgumentException("Can't find decoder for this image");
} else {
throw new IllegalArgumentException("Can't open stream for this image");
}
}
}
Java를 사용하여 Buffered Image 객체를 사용하여 이미지의 폭과 높이를 얻을 수 있습니다.
public void setWidthAndHeightImage(FileUploadEvent event){
byte[] imageTest = event.getFile().getContents();
baiStream = new ByteArrayInputStream(imageTest );
BufferedImage bi = ImageIO.read(baiStream);
//get width and height of image
int imageWidth = bi.getWidth();
int imageHeight = bi.getHeight();
}
이미지를 사용하여 버퍼링된 이미지를 가져오려면IO.read는 메모리에 이미지의 완전한 비압축 복사를 생성하기 때문에 매우 무거운 방법입니다.png의 경우 pngj와 코드를 사용할 수도 있습니다.
if (png)
PngReader pngr = new PngReader(file);
width = pngr.imgInfo.cols;
height = pngr.imgInfo.rows;
pngr.close();
}
byte[] bytes = file.getBytes();
InputStream inputStream = new ByteArrayInputStream(bytes);
BufferedImage image = ImageIO.read(inputStream);
imageWidth = image.getWidth();
imageHeight = image.getHeight();
그래서 불행히도 위에서 모든 답을 시도했지만 지칠 줄 모르는 노력 끝에 일을 시키지 못했다.그래서 제가 직접 해킹을 하기로 결심했고 저를 위해 이걸 하기로 했습니다.당신에게도 완벽하게 효과가 있을 거라고 믿어요.
앱에 의해 생성된 이미지의 너비를 얻기 위해 이 간단한 방법을 사용하고 있으며, 나중에 확인을 위해 업로드 할 수 있습니다.
참고: 액세스 스토리지에 대한 사용 권한을 매니페스트에서 활성화해야 합니다.
/정적으로 만들고 Global 클래스에 넣었기 때문에 한 곳에서만 참조하거나 액세스할 수 있으며, 수정 사항이 있으면 모두 한 곳에서 수행해야 합니다. java에서 DRY 컨셉을 유지하고 있습니다. (오류) : /
public static int getImageWidthOrHeight(String imgFilePath) {
Log.d("img path : "+imgFilePath);
// Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeFile(imgFilePath, o);
int width_tmp = o.outWidth, height_tmp = o.outHeight;
Log.d("Image width : ", Integer.toString(width_tmp) );
//you can decide to rather return height_tmp to get the height.
return width_tmp;
}
EMF 이미지 리더를 사용하지 않고 emf 파일의 크기를 가져오려면 코드를 사용합니다.
Dimension getImageDimForEmf(final String path) throws IOException {
ImageInputStream inputStream = new FileImageInputStream(new File(path));
inputStream.setByteOrder(ByteOrder.LITTLE_ENDIAN);
// Skip magic number and file size
inputStream.skipBytes(6*4);
int left = inputStream.readInt();
int top = inputStream.readInt();
int right = inputStream.readInt();
int bottom = inputStream.readInt();
// Skip other headers
inputStream.skipBytes(30);
int deviceSizeInPixelX = inputStream.readInt();
int deviceSizeInPixelY = inputStream.readInt();
int deviceSizeInMlmX = inputStream.readInt();
int deviceSizeInMlmY = inputStream.readInt();
int widthInPixel = (int) Math.round(0.5 + ((right - left + 1.0) * deviceSizeInPixelX / deviceSizeInMlmX) / 100.0);
int heightInPixel = (int) Math.round(0.5 + ((bottom-top + 1.0) * deviceSizeInPixelY / deviceSizeInMlmY) / 100.0);
inputStream.close();
return new Dimension(widthInPixel, heightInPixel);
}
언급URL : https://stackoverflow.com/questions/672916/how-to-get-image-height-and-width-using-java
'programing' 카테고리의 다른 글
| 운영 환경에서 스프링 부트 실행 파일 jar를 실행하려면 어떻게 해야 합니까? (0) | 2023.01.16 |
|---|---|
| Vuex 상태 생성에서 함수를 사용하는 방법 (0) | 2023.01.16 |
| ES6에서 "엄격한 사용"을 사용하는 것은 권장되지 않습니다. (0) | 2023.01.16 |
| PHP에서 2개의 어레이를 연결할 수 없습니다. (0) | 2023.01.16 |
| JavaScript에서 지정된 문자 앞에 있는 하위 문자열을 어떻게 잡습니까? (0) | 2023.01.16 |