2011-08-16 28 views
6

Tengo el código fuente del lenguaje C, para un sistema integrado, que contiene matrices de datos para una imagen en escala de grises de 8 bits por píxel. Estoy a cargo de documentar el software y me gustaría convertir este código fuente a un archivo JPEG (imagen).Convertir binario en escala de grises sin formato a JPEG

Aquí es un ejemplo de código:

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; 

Aquí están mis preguntas: (sí, en plural)

  1. ¿Qué aplicación (s) me recomiendan para convertir este archivo fuente a JPEG?
  2. ¿Puede GIMP o Paint importar un archivo CSV de datos?
  3. Si escribo esta aplicación personalizada, ¿qué bibliotecas Java existen para JPEG?
  4. ¿Qué bibliotecas existen en C# para realizar esta tarea?

que tienen los siguientes recursos a mi disposición: MS Visio 2010, Gimp, pintura, Java, Eclipse, MS Visual Studio 2010 Professional, wxWidgets, wxFrameBuilder, Cygwin.
Puedo escribir la aplicación personalizada en C#, Java, C o C++.

Gracias por su consejo.

+1

Considere usar PNG en lugar de JPEG para una imagen pequeña como esta. –

+1

Estoy de acuerdo con @Michael. Esto se ajusta a un formato sin pérdida, como png, mucho mejor que jpeg. La imagen parece ser pequeña y tiene bordes afilados que la hacen ajustarse png/gif más que jpeg. Jpeg no funciona bien con bordes afilados. – CodesInChaos

Respuesta

1

El problema con el uso de java será obtener los bytes como ints. Mientras lee, necesitará convertir a un int para capturar valores> 127 porque java no tiene bytes sin signo.

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); 
0

Puede utilizar la clase ImageIO en 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); 
+0

¿Funciona? ¿cómo sabrá la altura y el ancho? – musefan

+0

@musefan Leí una imagen en escala de grises y asumí que era una matriz de bytes de imagen con metadatos. – Andrew

+0

Supuse que no contiene metadatos debido a que el ancho y la altura se suministraron por separado. Además, el formato de archivo JPeg comienza con 0xFF 0xD8 ... tal vez algo para que el OP aclare, ya que esto bien podría ser datos ficticios para esta publicación – musefan

1

Respondo la pregunta 4 y puedo darle el código para hacer esto en C#. Es muy simple ...

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); 

También puede ser capaz de optimizar este código si usted mira alrededor de técnicas de optimización de mapa de bits (como el bloqueo de la memoria de mapa de bits)

EDITAR: Alternativa con poco bloqueo (debe ser mucho más rápido) ...

NOTA: No estoy 100% seguro sobre el PixelFormat utilizado al crear el objeto Bitmap, era mi mejor estimación de las opciones disponibles.

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

Gracias por el ejemplo. No hay criterios de rendimiento ya que la aplicación se ejecutará en una PC. –

+0

¿Puede ser una aplicación de "consola" o requiere la GUI? –

+1

@Thomas puede ser una aplicación de consola, pero debe agregar una referencia a 'System.Drawing.dll'. – CodesInChaos

Cuestiones relacionadas