如何在C#和.NET 3.5中减小图像的大小?

我有一个屏幕截图,我在我的移动应用程序中。 在磁盘上保存为png时,屏幕截图大约需要32 KB。

我将这些发送到中央SQL Server,32 KB太大了,我需要存储该屏幕截图(每天大约2500次)。

有什么样的技巧可以让它来节省更小的?

这是我现在使用的代码,它从Bitmap到字节(发送到服务器进行存储):

 MemoryStream stream = new MemoryStream(); _signatureImage.Save(stream, ImageFormat.Png); return stream.ToArray(); 

_signatureImage是一个Bitmap ,是有问题的屏幕截图。

这是我正在保存的屏幕截图的示例:

屏幕截图

想到的东西(但我不知道怎么做):

  1. 减少图像的实际高度和宽度(但希望以一种不会扭曲它的方式)。
  2. 将其更改为黑白图像(不确定我是否会看到任何真正的空间节省)
  3. 压缩它(我不喜欢这个,因为它不能从数据库中读取)。

注意,这一切都必须以编程方式完成,并且不能花费很长时间,因此复杂的图像处理已经完成。

谢谢你的帮助。

  private static Image ResizeImage(int newSize, Image originalImage) { if (originalImage.Width <= newSize) newSize = originalImage.Width; var newHeight = originalImage.Height * newSize / originalImage.Width; if (newHeight > newSize) { // Resize with height instead newSize = originalImage.Width * newSize / originalImage.Height; newHeight = newSize; } return originalImage.GetThumbnailImage(newSize, newHeight, null, IntPtr.Zero); } 

这应该适用于您的Bitmap对象Type并调整高度或宽度,具体取决于哪个适合您的图像尺寸。 它还将保持规模。

编辑:

您可以创建一个新的Bitmap对象,并将原始图像的大小调整为该Bitmap对象。

 Bitmap b = new Bitmap(newWidth, newHeight); Graphics g = Graphics.FromImage((Image)b); g.InterpolationMode = InterpolationMode.HighQualityBicubic; g.DrawImage(imgToResize, 0, 0, newWidth, newHeight); g.Dispose(); return (Image)b; 

我没有安装Compact Framework,但似乎这应该对你有用。

如果颜色深度不是问题,您可以将其更改为黑白或16色模式。 应该比png的24-bpp(或alpha-32-bpp)存储要求节省大量资金。 要考虑的另一件事是将其保存为256色模式的.gif文件。

当你保存签名数据时,我认为改变图像的尺寸是个坏主意。 您也可以考虑应用像zip这样的无损压缩,但这可能比您需要的计算密集程度更高。

将调色板更改为较低的颜色深度。 看看这个问题 (好好看看answert),显示转换为1bpp。 您可以使用8bpp而不是1bpp,并且可以节省大量的资金。 转换机制与显示的相同。

编辑

开箱即用,您可能还会考虑从屏幕上方发送数据点和签名向量,让服务器为您重新创建屏幕。 如果尺寸确实是个大问题,我可能会对此进行调查。

编辑2

如果简单地调整图像大小是一个合理的解决方案(这显然会丢失数据),那么您可以使用SDF中的Imaging命名空间来创建缩略图,正如Alex在此解释的那样 。

如果单色图像可以接受,您可以尝试TIFF G4(无损压缩)。 众所周知,TIFF G4在文件大小方面非常有效,可以存储黑白图像。 不幸的是,我没有任何关于如何与PNG比较的信息,但值得研究。

以下是有关如何在C#中执行此操作的信息和示例

尝试转换为纯单色位图。 它们非常小,因为它们每个像素仅使用一位。

编辑:我是个骗子。 刚刚在Paint中尝试了这个,它与原来的20k相比大约是40k。 我可以发誓那些在我之前使用它们时节省了大量空间……

编辑编辑:好的,显然他们确实有大量的节省。 对于这些图像来说,PNG可以节省更多。 刚尝试了一个16色的位图,它将它吹得高达150k。

编辑编辑编辑:但是,单色位图拉伸到9k字节,而PNG甚至压缩为20k。


因此,看起来如果您想要进入压缩路径,您可以先转换为单色位图,然后压缩大约为PNG大小一半的图像。

您还可以从图像中删除一些信息。 例如,在该屏幕上,唯一真正需要保留图像的是签名。 可以撕掉上面和下面的条,数字信息可以这样发送并单独存储。

用一张照片来点燃Fireworks,这将是不一样但应该给出一个想法

 66% quality JPG with no smoothing is 17.5k PNG8 with 256 colours is 58K (down to 42 using websnap palette) PNG8 with black and white palette is 14k 

请注意,由于存在大量相同颜色的连续分组,因此许多图像文件会因屏幕截图而变小,对于黑白可能尤其如此。 它可能还取决于用于转换图像的算法,但你可能想要随意找到你能找到的任何东西……

FWIW在SQL Server中物理存储图像不是最佳解决方案。 如果您正在使用Sql Server 2008,您应该查看文件流支持,它将允许您将物理映像存储在磁盘上并访问它们,就好像它们是SQL Server内部的一样。 这很可能会减轻您担心文件大小的需要。