2016-11-08 47 views
-1

我在這裏有一個小問題,如果有人可以幫助我,我會很高興。 我試圖讓下操作Java - 圖像BMP標頭

  1. 讀取一個BMP圖像
  2. 將圖像轉換成一個byte []
  3. 90度(字節數組)
  4. 而寫,旋轉圖像在一些文件夾中的新圖像

我的問題是...在我試圖寫新圖像的那一刻,我有一些BMP頭的問題,我不知道爲什麼。如果有人知道這個答案,請給我一些建議。

轉換圖像劃分成字節[]

private static byte[] convertAnImageToPixelsArray(File file) throws FileNotFoundException { 
    FileInputStream fis = new FileInputStream(file); 

    ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
    byte[] buf = new byte[1024]; 
    try { 
     for (int readNum; (readNum = fis.read(buf)) != -1;) { 
      bos.write(buf, 0, readNum); 
     } 
    } catch (IOException ex) { 
     Logger.getLogger(ConvertImage.class.getName()).log(Level.SEVERE, null, ex); 
    } 
    return bos.toByteArray(); 
} 

旋轉

private static byte[] rotate(double angle, byte[] pixels, int width, int height) { 
    final double radians = Math.toRadians(angle), cos = Math.cos(radians), sin = Math.sin(radians); 
    final byte[] pixels2 = new byte[pixels.length]; 
    for (int x = 0; x < width; x++) { 
     for (int y = 0; y < height; y++) { 
      final int 
        centerx = width/2, 
        centery = height/2, 
        m = x - centerx, 
        n = y - centery, 
        j = ((int) (m * cos + n * sin)) + centerx, 
        k = ((int) (n * cos - m * sin)) + centery; 
      if (j >= 0 && j < width && k >= 0 && k < height) 
       pixels2[(y * width + x)] = pixels[(k * width + j)]; 
     } 
    } 
    arraycopy(pixels2, 0, pixels, 0, pixels.length); 
    return pixels2; 
} 

轉換的字節[]爲圖像

private static void convertArrayPixelsIntoImage(byte[] bytes) throws IOException { 
    ByteArrayInputStream bis = new ByteArrayInputStream(bytes); 
    Iterator<?> readers = ImageIO.getImageReadersByFormatName("bmp"); 

    ImageReader reader = (ImageReader) readers.next(); 
    Object source = bis; 
    ImageInputStream iis = ImageIO.createImageInputStream(source); 
    reader.setInput(iis, true); 
    ImageReadParam param = reader.getDefaultReadParam(); 

    Image image = reader.read(0, param); 
    BufferedImage bufferedImage = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_RGB); 

    Graphics2D g2 = bufferedImage.createGraphics(); 
    g2.drawImage(image, null, null); 

    File imageFile = new File("Images/Output.bmp"); 
    ImageIO.write(bufferedImage, "bmp", imageFile); 
} 

主要:

public static void main(String[] args) throws IOException { 
    File file = new File("Images/Input-1.bmp"); 
    Image img = ImageIO.read(file); 
    convertArrayPixelsIntoImage(rotate(90,convertAnImageToPixelsArray(file),img.getWidth(null),img.getHeight(null))); 
} 

這裏它的錯誤消息:

異常在線程 「主」 javax.imageio.IIOException:無法讀取圖像頭。

有什麼建議嗎?

+0

你是怎麼調用這些方法的?請顯示你打電話給他們的方法。 –

+0

我已經添加和現在的主要功能。 –

+0

您正在旋轉整個圖像文件的內容,包括標題,因此會破壞標題。但爲什麼麻煩讀兩遍?你用'ImageIO.read'和'convertAnImageToPixelsArray'讀取圖像 - 這是多餘的。 –

回答

1

問題在於,當您旋轉圖像時,您沒有考慮到BMP文件的結構。

您只是從文件中讀取byte[],正如您可以從任何文件讀取的一樣 - 它只是一個字節流。

但在你rotate方法,你假定像素值是:每個像素

  • 1個字節;
  • 從數組的開始處開始。

事實並非如此。除了每個像素將幾乎肯定由多個字節編碼的事實以外,BMP file format還以頭和其他元數據開頭。

雖然你明顯可以弄清楚如何正確解碼數據,但我強烈反對。您已經在使用ImageIO讀取圖像(Image img = ImageIO.read(file);),所以您不必重新發明輪子:只需使用Java現有的圖像處理功能即可。

+0

問題是...我需要重新安裝輪子,因爲我需要一些速度。在正常情況下,我可以** BufferedImage **旋轉這個圖像,但這種方法會減慢...我需要更快的東西,你有什麼想法? –

+0

您需要了解BMP文件格式,瞭解其結構,並調整您的代碼以正確處理它。但是你幾乎肯定會做錯事,錯過邊緣案例,做得不夠有效率等等,結果浪費了一大堆時間。找到一個現有的實現。 –