2

尝试将巨大的图像(例如 9000x9000 像素的图像)加载到 Bitmap 对象中可能会产生内存不足错误、“参数无效”错误以及毫无疑问的其他相关问题。

如何从磁盘加载 9000x9000 像素的图像,最终在保存回磁盘之前调整其大小,而不会导致致命错误(例如内存不足)?

让我们假设一个 32 位环境,具有 2gb 的 ram,C# 4.0,并且将使用 jpg、gif、bmp、tif、png 的图像格式。

我尝试了以下 3 个片段,每个片段都因内存错误而失败。

尝试1:

using (Bitmap srcImg = new Bitmap(@"C:\9000x9000.jpg"))
{
    // boom
}

尝试2:

using (Image srcImg = Image.FromFile(@"C:\9000x9000.jpg"))
{
    // kapow
}

尝试 3:

using (FileStream fs = new FileStream(@"C:\9000x9000.jpg", FileMode.Open, FileAccess.Read))
{
    using (Image srcImg = Image.FromStream(fs))
    {
        // kelly clarkson
    }
}

我对一个可能的解决方案的想法是将图像文件直接加载到一个数组中(这样你就没有 Bitmap 对象的巨大开销),以某种方式使用该数组将其调整为更小(可能需要为不同的图像格式标题编码? ),在最终转换为可管理大小的 Bitmap 对象之前。

想法或可能的解决方案?

4

2 回答 2

1

看看AForge.Net 库据说它擅长处理大文件。

于 2012-11-18T21:21:53.660 回答
0

以下是我为其工作所遵循的步骤:

1.转到http://www.opennetcf.org/PermaLink.aspx?guid=d57ace50-2762-4b19-b07d-39421829d410并下载下载 SDF 2.0 Beta1 Redistributables。安装。

2.在针对 PPC 2003 SE 设备的 VS.NET 2005 中创建一个智能设备项目。我必须右键单击我的项目并选择“升级”以确保它针对的是 .NET CF v2.0 而不是 .NET CF 1.1 SP3。

3.我添加了OpenNETCF.dll和OpenNETCF.Drawing.dll文件作为默认安装目录(C:\Program Files\OpenNETCF\Smart Device Framework 2.0)的引用

4.我在表单上创建了一个带有图片框的简单应用程序,它会在加载表单时加载我的图像。以下是相关代码,其中一些是从 Alex Feinman 的网络日志中复制而来的:

#region Using directives
using System;
using System.Drawing;
using System.Collections;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using OpenNETCF.Drawing.Imaging;
using System.IO;
#endregion

....

const string szFileName = @"\Storage Card\TEMP\2MBJPEG.JPG";



private void Form1_Load(object sender, EventArgs e)
{
IBitmapImage imageBitmap;
FileStream fsImage;
fsImage = new FileStream(
    szFileName,
    FileMode.Open);
imageBitmap = CreateThumbnail(
    fsImage,
    new Size(100, 100));

Bitmap bm = ImageUtils.IBitmapImageToBitmap(
    imageBitmap);
pictureBox1.Image = bm;
}


static public IBitmapImage CreateThumbnail(Stream stream, Size size)
{
IBitmapImage imageBitmap;
ImageInfo ii;
IImage image;
ImagingFactory factory = new ImagingFactoryClass();
    factory.CreateImageFromStream(
    new StreamOnFile(stream), 
    out image);
image.GetImageInfo(out ii);
factory.CreateBitmapFromImage(
    image, 
    (uint)size.Width, 
    (uint)size.Height,
    ii.PixelFormat, 
    InterpolationHint.InterpolationHintDefault, 
    out imageBitmap);
    return imageBitmap;
}
于 2013-05-21T12:12:57.577 回答