2011-08-16 16 views
6

Ho codice sorgente in linguaggio C, per un sistema incorporato, contenente matrici di dati per un'immagine in scala di grigi a 8 bit per pixel. Sono incaricato di documentare il software e mi piacerebbe convertire questo codice sorgente in un file JPEG (immagine).Converti binario in scala di grigi crudo in JPEG

Ecco un esempio di codice:

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; 

Ecco le mie domande: (sì, al plurale)

  1. Quale applicazione (s) mi consiglia per la conversione di questo file sorgente in JPEG?
  2. GIMP o Paint può importare un file CSV di dati?
  3. Se scrivo questa applicazione personalizzata, quali librerie Java esistono per JPEG?
  4. Quali librerie esistono in C# per l'esecuzione di questa attività?

ho le seguenti risorse a mia disposizione: MS Visio 2010, Gimp, Paint, Java, Eclipse, MS Visual Studio 2010 Professional, wxWidgets, wxFrameBuilder, Cygwin.
Posso scrivere l'applicazione personalizzata in C#, Java, C o C++.

Grazie per il vostro consiglio.

+1

Considerare l'utilizzo di PNG anziché JPEG per un'immagine piccola come questa. –

+1

Sono d'accordo con @Michael. Questo si adatta ad un formato lossless come png molto meglio di jpeg. L'immagine sembra essere piccola e ha bordi taglienti che lo rendono adatto a png/gif più di jpeg. Jpeg non si comporta bene con spigoli vivi. – CodesInChaos

risposta

1

Il problema con l'utilizzo di java sarà quello di ottenere i byte come ints. Durante la lettura devi convertire in un int per acquisire valori> 127 perché java non ha byte senza segno.

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

È possibile utilizzare semplicemente la classe ImageIO in 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

Funziona? come saprà l'altezza e la larghezza? – musefan

+0

@musefan Ho letto l'immagine in scala di grigi e ho pensato che fosse una matrice di byte immagine con metadati. – Andrew

+0

Ho pensato che non contenga metadati perché la larghezza e l'altezza sono state fornite separatamente. Inoltre, il formato file JPeg inizia con 0xFF 0xD8 ... forse qualcosa per l'OP da chiarire poichè questo potrebbe essere un dato fittizio per questo post – musefan

1

Posso rispondere alla domanda 4 e posso darti il ​​codice per farlo in C#. E 'molto semplice ...

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

Si può anche essere in grado di ottimizzare questo codice se si guarda intorno per tecniche di ottimizzazione bitmap (come il blocco della memoria bitmap)

EDIT: alternativa con po' blocco (dovrebbe essere molto più veloce) ...

NOTA: non sono sicuro al 100% circa il PixelFormat utilizzato durante la creazione dell'oggetto Bitmap - è stata la mia ipotesi migliore per le opzioni disponibili.

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

Grazie per l'esempio. Non ci sono criteri di rendimento in quanto l'applicazione verrà eseguita su un PC. –

+0

Può trattarsi di un'applicazione "console" o richiede la GUI? –

+1

@Thomas può essere un'applicazione console, ma è necessario aggiungere un riferimento a 'System.Drawing.dll'. – CodesInChaos

Problemi correlati