2011-08-16 91 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

相关问题