Конвертировать двоичные файлы в градациях серого в формат JPEG - PullRequest
6 голосов
/ 16 августа 2011

У меня есть исходный код на языке C для встроенной системы, содержащий массивы данных для изображения в оттенках серого размером 8 бит на пиксель.Я отвечаю за документирование программного обеспечения и хотел бы преобразовать этот исходный код в файл JPEG (изображение).

Вот пример кода:

const unsigned char grayscale_image[] = {
0, 0, 0, 0, 0, 0, 0, 74, 106, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 
159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 146, 93, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
//...
};
const unsigned int height = 41;
const unsigned int width = 20;

Вотмои вопросы: (да, множественное число)

  1. Какие приложения вы рекомендуете для преобразования этого исходного файла в JPEG?
  2. Может ли GIMP или Paint импортировать файл данных CSV?
  3. Если я напишу это пользовательское приложение, какие библиотеки Java существуют для JPEG?
  4. Какие библиотеки существуют в C # для выполнения этой задачи?

У меня есть следующие ресурсыВ моем распоряжении: MS Visio 2010, Gimp, Paint, Java, Eclipse, MS Visual Studio 2010 Professional, wxWidgets, wxFrameBuilder, Cygwin.
Я могу написать собственное приложение на C #, Java, C или C ++.

Спасибо за ваш совет.

Ответы [ 3 ]

2 голосов
/ 16 августа 2011

Проблема с использованием Java будет заключаться в получении байтов в виде целых чисел. Во время чтения вам нужно преобразовать в int, чтобы получить значения> 127, потому что в Java нет неподписанных байтов.

int height=41;
int width=20;
int[] data = {...};

BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
for ( int x = 0; x < width; x++ ) {
  for ( int y = 0; y < height; y++ ) {
  // fix this based on your rastering order
  final int c = data[ y * width + x ];
  // all of the components set to the same will be gray
  bi.setRGB(x,y,new Color(c,c,c).getRGB() );
  }
}
File out = new File("image.jpg");
ImageIO.write(bi, "jpg", out);
1 голос
/ 16 августа 2011

Я могу ответить на вопрос 4 и дать вам код для этого на c #.Это очень просто ...

int width = 20, height = 41;
byte[] grayscale_image = {0, 0, 0, ...};
System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(width, height);
int x = 0;
int y = 0;
foreach (int i in grayscale_image)
{
    bitmap.SetPixel(x, y, System.Drawing.Color.FromArgb(i, i, i));
    x++;
    if (x >= 41)
    {
        x = 0;
        y++;
    }
}
bitmap.Save("output.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);

Вы также можете оптимизировать этот код, если посмотрите на методы оптимизации растрового изображения (например, блокировка памяти растрового изображения)

РЕДАКТИРОВАТЬ : Альтернатива с битовой блокировкой (должна быть намного быстрее) ...

ПРИМЕЧАНИЕ. Я не на 100% уверен в том, что PixelFormat использовался при создании объекта Bitmap - я был моим лучшим предположением о доступных параметрах.

int width = 20, height = 41;
byte[] grayscale_image = {0, 0, 0, ...};
System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(width, height, PixelFormat.Format8bppIndexed);

System.Drawing.Imaging.BitmapData bmpData = bitmap.LockBits(
                     new Rectangle(0, 0, bitmap.Width, bitmap.Height),
                     ImageLockMode.WriteOnly, bitmap.PixelFormat);

System.Runtime.InteropServices.Marshal.Copy(bytes, 0, bmpData.Scan0, bytes.Length);

bitmap.UnlockBits(bmpData);

return bitmap;
0 голосов
/ 16 августа 2011

Вы можете просто использовать класс ImageIO в Java.

BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GREY);

Graphics2D g2 = bi.createGraphics();

//loop through and draw the pixels here   

File out = new File("Myimage.jpg");
ImageIO.write(bi, "jpg", out);
...