2016-11-29 11 views
2

Я сжимаю изображение, выполняющее сжатие Jpeg на Java, а затем изменяя его размер перед сохранением. Я сохраняю высоту хранения как 480 и вычисляет height на основе соотношения сторон, поэтому сохранить исходное соотношение height:width.Java: getHeight() на BufferedImage возвращает ширину изображения, а getWidth() возвращает высоту изображения

Это код, я использую

String inputImagePath = "1.JPG"; 
String outputImagePath = "Test Compression\\" + "1.JPG"; 

File imageFile = new File(inputImagePath); 
File compressedImageFile = new File(outputImagePath); 

int height = 640; 

System.out.print("Conversion Start!\n"); 

if (imageFile != null) 
{ 

    InputStream is = new FileInputStream(imageFile); 
    OutputStream os = new FileOutputStream(compressedImageFile); 

    float quality = 0.2 f; 

    BufferedImage image = ImageIO.read(is); 

    double aspectRatio = (double) image.getWidth()/image.getHeight(); 

    width = (int)(height * aspectRatio); 
    System.out.println("Original height = " + image.getHeight() + " Original width = " + image.getWidth()); 
    System.out.println(" aspect ratio = " + aspectRatio); 
    System.out.println("height = " + height + " width = " + width + " aspect ratio = " + aspectRatio); 

    BufferedImage resizedImage = new BufferedImage(width, height, image.getType()); 
    Graphics2D g = resizedImage.createGraphics(); 
    g.drawImage(image, 0, 0, width, height, null); 
    g.dispose(); 

    Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName("jpg"); 

    if (!writers.hasNext()) 
     throw new IllegalStateException("No writers found"); 

    ImageWriter writer = (ImageWriter) writers.next(); 
    ImageOutputStream ios = ImageIO.createImageOutputStream(os); 
    writer.setOutput(ios); 

    ImageWriteParam param = writer.getDefaultWriteParam(); 
    param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); 
    param.setCompressionQuality(quality); 

    writer.write(null, new IIOImage(resizedImage, null, null), param); 
} 

System.out.print("Conversion compete!"); 

Здесь метаданные изображения

Here width = 1920, height = 2560

Вот печатное содержание:

Original height = 1920 Original width = 2560 
aspect ratio = 1.3333333333333333 

height = 480 width = 640 
aspect ratio = 1.3333333333333333 

Я применил код другие изображения, которые на самом деле имели width > height, и у меня было нет проблем с ротацией. Эта проблема rotaion возникает только для изображений с height > width Насколько я знаю, в моем коде нет ничего плохого, я должен упустить что-то, связанное с функциями getHeight() и getWidth(). Пожалуйста, помогите мне

+0

Могли бы вы обновить ваш образец кода с переменной высоты, а? Кажется, он отсутствует. – Flipbed

+0

Я обновляю код переменной 'height'. Я получил желаемые результаты, используя [экстрактор метаданных] (https://github.com/drewnoakes/metadata-extractor), как предложил Сергей Гринев. Я разместил его ниже. –

ответ

3

В jpeg-изображениях, которые Java не распознает по умолчанию, могут быть метаданные вращения.

Он выглядит так: Orientation : rotate 90 в свойствах jpeg.

Вам нужно 3-й библиотека партии, чтобы справиться с этим, см How to rotate JPEG images based on the orientation metadata?

1

Для будущих ссылок, я получил через ссылку, приведенный Сергей Гринев и изменили код немного и получил желаемый результат. Вот код

Metadata metadata = ImageMetadataReader.readMetadata(imageFile); 
 
Directory directory = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class); 
 
\t \t \t 
 
int orientation = 1; 
 
try{ 
 
orientation = directory.getInt(ExifIFD0Directory.TAG_ORIENTATION); 
 
} catch (MetadataException me) { 
 
System.out.println("Could not get orientation"); 
 
} 
 

 
int orgWidth = image.getWidth(); 
 
int orgHeight = image.getHeight(); 
 
\t \t \t 
 
double orgAspectRatio = (double)orgWidth/orgHeight; 
 
\t \t \t 
 
\t \t \t 
 
AffineTransform affineTransform = new AffineTransform(); 
 
AffineTransformOp affineTransformOp; 
 
BufferedImage orientedImage = new BufferedImage(image.getHeight(), image.getWidth(), image.getType()); 
 
\t \t 
 
boolean rotation = false; 
 
\t   
 
switch (orientation) { 
 
    case 1: 
 
     \t orientedImage = image; 
 
     break; 
 
    case 2: // Flip X 
 
     affineTransform.scale(-1.0, 1.0); 
 
     affineTransform.translate(-orgWidth, 0); 
 
    \t affineTransformOp = new AffineTransformOp(affineTransform, AffineTransformOp.TYPE_BILINEAR); 
 
\t  orientedImage = affineTransformOp.filter(image, orientedImage); 
 
\t  break; 
 
    case 3: // PI rotation 
 
      affineTransform.translate(orgWidth, orgHeight); 
 
      affineTransform.rotate(Math.PI); 
 
      affineTransformOp = new AffineTransformOp(affineTransform,AffineTransformOp.TYPE_BILINEAR); 
 
     orientedImage = affineTransformOp.filter(image, orientedImage); 
 
     break; 
 
    case 4: // Flip Y 
 
      affineTransform.scale(1.0, -1.0); 
 
      affineTransform.translate(0, -orgHeight); 
 
\t \t affineTransformOp = new AffineTransformOp(affineTransform, AffineTransformOp.TYPE_BILINEAR); 
 
      orientedImage = affineTransformOp.filter(image, orientedImage); 
 
      break; 
 
    case 5: // - PI/2 and Flip X 
 
     \t rotation = true; 
 
      affineTransform.rotate(-Math.PI/2); 
 
      affineTransform.scale(-1.0, 1.0); 
 
\t \t \t affineTransformOp = new AffineTransformOp(affineTransform, AffineTransformOp.TYPE_BILINEAR); 
 
      orientedImage = affineTransformOp.filter(image, orientedImage); 
 
      break; 
 
    case 6: // -PI/2 and -width 
 
     \t rotation = true; 
 
      affineTransform.translate(orgHeight, 0); 
 
      affineTransform.rotate(Math.PI/2); 
 
\t \t \t affineTransformOp = new AffineTransformOp(affineTransform, AffineTransformOp.TYPE_BILINEAR); 
 
      orientedImage = affineTransformOp.filter(image, orientedImage); 
 
      break; 
 
    case 7: // PI/2 and Flip 
 
     \t rotation = true; 
 
      affineTransform.scale(-1.0, 1.0); 
 
      affineTransform.translate(-orgHeight, 0); 
 
      affineTransform.translate(0, orgWidth); 
 
      affineTransform.rotate(3 * Math.PI/2); 
 
\t \t \t affineTransformOp = new AffineTransformOp(affineTransform, AffineTransformOp.TYPE_BILINEAR); 
 
      orientedImage = affineTransformOp.filter(image, orientedImage); 
 
      break; 
 
    case 8: // PI/2 
 
     \t rotation = true; 
 
      affineTransform.translate(0, orgWidth); 
 
      affineTransform.rotate(3 * Math.PI/2); 
 
\t \t \t affineTransformOp = new AffineTransformOp(affineTransform, AffineTransformOp.TYPE_BILINEAR); 
 
      orientedImage = affineTransformOp.filter(image, orientedImage); 
 
      break; 
 
    default: 
 
     \t orientedImage = image; 
 
      break; 
 
     }  
 
\t   
 
double aspectRatio; 
 
\t   
 
if(rotation){ 
 
    \t aspectRatio = (double)orientedImage.getWidth()/orientedImage.getHeight(); 
 
     \t width = outWidth; 
 
     \t height = (int)(width/aspectRatio); 
 
     } 
 
     else{ 
 
     \t aspectRatio = (double)orientedImage.getWidth()/orientedImage.getHeight(); 
 
      \t width = (int)(height*aspectRatio); 
 
     }