2011-08-16 66 views
6

我擁有C語言源代碼,適用於嵌入式系統,包含8位每像素灰度圖像的數據陣列。我負責記錄軟件,並且我想將此源代碼轉換爲JPEG(圖像)文件。將原始灰度二進制轉換爲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. 什麼應用程序(S)你推薦這個源文件轉換爲JPEG?
  2. GIMP或Paint可以導入CSV文件的數據嗎?
  3. 如果我編寫這個自定義應用程序,那麼對於 JPEG存在哪些Java庫?
  4. C#中有哪些庫用於完成此任務?

我有以下資源可供使用:MS Visio 2010,Gimp,Paint,Java,Eclipse,MS Visual Studio 2010 Professional,wxWidgets,wxFrameBuilder,Cygwin。
我可以用C#,Java,C或C++編寫自定義應用程序。

感謝您的建議。

+1

考慮使用PNG而不是JPEG這樣的小圖像。 –

+1

我同意@Michael。這適合像JPEG等無損格式比JPEG更好。圖像看起來很小,並有銳利的邊緣,使其比png/gif更適合jpeg。 Jpeg不擅長處理尖銳的邊緣。 – CodesInChaos

回答

1

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

您可以在java中使用ImageIO類。

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

這是行不通的嗎?它如何知道高度和寬度? – musefan

+0

@musefan我讀了灰度圖像,並假設它是一個包含元數據的圖像字節數組。 – Andrew

+0

我認爲它不包含元數據,因爲寬度和高度是分開提供的。此外,JPeg文件格式以0xFF 0xD8開頭......可能是OP要清除的東西,因爲這可能是這篇文章的虛擬數據 – musefan

1

我可以回答問題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 - 這是我對可用選項的最佳猜測。

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

感謝您的示例。由於應用程序將在PC上運行,因此沒有性能標準。 –

+0

這是一個「控制檯」應用程序還是需要GUI? –

+1

@Thomas它可以是一個控制檯應用程序,但是你需要添加一個對'System.Drawing.dll'的引用。 – CodesInChaos