2014-10-27 2 views
1

Задайте задачу создания BMP-файла из матрицы int RGB и чтения этой матрицы из изображения BMP.java create BMP image from pixel matrix and reverse

Я использовал этот класс для создания BMP-файла, но это, кажется, что это трудно повернуть вспять этот подход для получения rgbValues массива из изображения:

/** 
* Class for creating bmp images from the pixel matrix (an int matrix). 
* @author eafkuor 
* @link http://forum.codecall.net/topic/62457-creating-a-bmp-image-in-java/ 
*/ 
import java.io.File; 
import java.io.FileOutputStream; 

public class BMP { 
    private final static int BMP_CODE = 19778; 

    byte[] bytes; 

    public void saveBMP(String filename, int[][] rgbValues) { 
     try { 
      FileOutputStream fos = new FileOutputStream(new File(filename)); 

      bytes = new byte[54 + 3 * rgbValues.length * rgbValues[0].length + getPadding(rgbValues[0].length) * rgbValues.length]; 

      saveFileHeader(); 
      saveInfoHeader(rgbValues.length, rgbValues[0].length); 
      saveRgbQuad(); 
      saveBitmapData(rgbValues); 

      fos.write(bytes); 

      fos.close(); 

     } catch (Exception ignored) {} 

    } 

    private void saveFileHeader() { 
     byte[] a = intToByteCouple(BMP_CODE); 
     bytes[0] = a[1]; 
     bytes[1] = a[0]; 

     a = intToFourBytes(bytes.length); 
     bytes[5] = a[0]; 
     bytes[4] = a[1]; 
     bytes[3] = a[2]; 
     bytes[2] = a[3]; 

     //data offset 
     bytes[10] = 54; 
    } 

    private void saveInfoHeader(int height, int width) { 
     bytes[14] = 40; 

     byte[] a = intToFourBytes(width); 
     bytes[22] = a[3]; 
     bytes[23] = a[2]; 
     bytes[24] = a[1]; 
     bytes[25] = a[0]; 

     a = intToFourBytes(height); 
     bytes[18] = a[3]; 
     bytes[19] = a[2]; 
     bytes[20] = a[1]; 
     bytes[21] = a[0]; 

     bytes[26] = 1; 

     bytes[28] = 24; 
    } 

    private void saveRgbQuad() { 

    } 

    private void saveBitmapData(int[][] rgbValues) { 
     int i; 

     for (i = 0; i < rgbValues.length; i++) { 
      writeLine(i, rgbValues); 
     } 

    } 

    private void writeLine(int row, int[][] rgbValues) { 
     final int offset = 54; 
     final int rowLength = rgbValues[row].length; 
     final int padding = getPadding(rgbValues[0].length); 
     int i; 

     for (i = 0; i < rowLength; i++) { 
      int rgb = rgbValues[row][i]; 
      int temp = offset + 3 * (i + rowLength * row) + row * padding; 

      bytes[temp] = (byte) (rgb >> 16); 
      bytes[temp + 1] = (byte) (rgb >> 8); 
      bytes[temp + 2] = (byte) rgb; 
     } 
     i--; 
     int temp = offset + 3 * (i + rowLength * row) + row * padding + 3; 

     for (int j = 0; j < padding; j++) 
      bytes[temp + j] = 0; 

    } 

    private byte[] intToByteCouple(int x) { 
     byte[] array = new byte[2]; 

     array[1] = (byte) x; 
     array[0] = (byte) (x >> 8); 

     return array; 
    } 

    private byte[] intToFourBytes(int x) { 
     byte[] array = new byte[4]; 

     array[3] = (byte) x; 
     array[2] = (byte) (x >> 8); 
     array[1] = (byte) (x >> 16); 
     array[0] = (byte) (x >> 24); 

     return array; 
    } 

    private int getPadding(int rowLength) { 

     int padding = (3 * rowLength) % 4; 
     if (padding != 0) 
      padding = 4 - padding; 


     return padding; 
    } 
} 

Есть ли Java Lib для изготовления таких вещей? Или, может быть, кто-то может предложить, как отменить BMP-файл?

+0

javax.imageio.ImageIO должен справиться с этим для вас. – BarrySW19

+0

@ BarrySW19 не обеспечивает обработку BMP – ovnia

+0

Он должен - в моей системе «System.out.println (Arrays.toString (ImageIO.getReaderFormatNames())); печатает "[BMP, BMP, JPG, JPG, wbmp, jpeg, png, JPEG, PNG, WBMP, GIF, gif]", и я получаю "[jpg, BMP, BMP, JPG, JPEG, WBMP, PNG, JPEG, PNG , WBMP, GIF, gif] для писателей. Что вы отдаете? Разработчики находятся в пакете com.sun.imageio.plugins.bmp, который должен иметь все стандартные Oracle JDK. – BarrySW19

ответ

1

Использование API - это, на мой взгляд, ленивая вещь, если задача легко реализовать, и вы могли бы лучше понять, что происходит за кулисами. После того, как вы это сделали хотя бы один раз, вы можете использовать API с хорошей совестью. В конце вы используете СЛЕДУЕТ использовать API, потому что рабочий код, вероятно, очень мощный и безопасный в использовании, чем ваша собственная версия.

Обращение к изображению - очень простая вещь, по крайней мере, в теории. Процесс состоит из двух этапов:

  1. положить цветную матрицу изображения в память
  2. создать новый образ, так что каждый пиксель, начиная с левой стороны, выбирается из образа в памяти, только начиная с право.

В качестве иллюстрации:

Скажем, у нас есть изображение, которое 4px по ширине и высоте 4px в. 0 указывает, что пиксель черный, а 1 означает, что он белый.

Таким образом, у нас есть на практике двоичная матрица 4x4. Составим его следующим образом:

[1][0] 
[1][0] 

Чтобы изменить его, мы просто скопировать массив в новую матрицу 4x4, но мы копируем значение в новую матрицу, начиная с правой стороны:

[1][0] => [0][1] 
[1][0] => [0][1] 

И теперь у нас есть обратное изображение:

[0][1] 
[0][1] 

Это идея.

В контексте RGB матрица исходного изображения будет выглядеть примерно так:

[rgb(255, 255, 255)][rgb(0, 0, 0)] 
[rgb(255, 255, 255)][rgb(0, 0, 0)] 

Теперь иди узнать, как извлечь цвет каждого пикселя и записать его на новый. Это непростая задача.

+0

Мне нужен ленивый способ). Потому что это не главная задача.и, фактически, все не так просто, как вы описали: есть заголовки и некоторые другие функции формата BMP, которые должны быть реализованы в файле – ovnia