使用.NET提供的图像文件编解码器,能否对大小进行编码的图像有限制?
我正在尝试对大于4GB的图像进行编码,但是使用.bmp、.jpg、.png或.tif编码器时会出现问题(或者输出的文件无法读取)。当我将图像大小降低到小于2GB时,使用.jpg编码器可以正常工作,但是使用.bmp、.tif或.png编码器则不行。
我的下一个尝试将是尝试libtiff,因为我知道tiff文件适用于大型图像。什么是适用于大型图像的好文件格式?或者我只是遇到了文件格式的限制?
(所有这些都在64位操作系统(WinXP 64)上完成,具有8 GB的RAM,并使用x64架构编译。)
我正在尝试对大于4GB的图像进行编码,但是使用.bmp、.jpg、.png或.tif编码器时会出现问题(或者输出的文件无法读取)。当我将图像大小降低到小于2GB时,使用.jpg编码器可以正常工作,但是使用.bmp、.tif或.png编码器则不行。
我的下一个尝试将是尝试libtiff,因为我知道tiff文件适用于大型图像。什么是适用于大型图像的好文件格式?或者我只是遇到了文件格式的限制?
(所有这些都在64位操作系统(WinXP 64)上完成,具有8 GB的RAM,并使用x64架构编译。)
Random r = new Random((int)DateTime.Now.Ticks);
int width = 64000;
int height = 64000;
int stride = (width % 4) > 0 ? width + (width % 4) : width;
UIntPtr dataSize = new UIntPtr((ulong)stride * (ulong)height);
IntPtr p = Program.VirtualAlloc(IntPtr.Zero, dataSize, Program.AllocationType.COMMIT | Program.AllocationType.RESERVE, Program.MemoryProtection.READWRITE);
Bitmap bmp = new Bitmap(width, height, stride, PixelFormat.Format8bppIndexed, p);
BitmapData bd = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, bmp.PixelFormat);
ColorPalette cp = bmp.Palette;
for (int i = 0; i < cp.Entries.Length; i++)
{
cp.Entries[i] = Color.FromArgb(i, i, i);
}
bmp.Palette = cp;
unsafe
{
for (int y = 0; y < bd.Height; y++)
{
byte* row = (byte*)bd.Scan0.ToPointer() + (y * bd.Stride);
for (int x = 0; x < bd.Width; x++)
{
*(row + x) = (byte)r.Next(256);
}
}
}
bmp.UnlockBits(bd);
bmp.Save(@"c:\test.jpg", ImageFormat.Jpeg);
bmp.Dispose();
Program.VirtualFree(p, UIntPtr.Zero, 0x8000);
我还尝试使用固定的GC内存区域,但是这种方式的限制是小于2GB。
Random r = new Random((int)DateTime.Now.Ticks);
int bytesPerPixel = 4;
int width = 4000;
int height = 4000;
int padding = 4 - ((width * bytesPerPixel) % 4);
padding = (padding == 4 ? 0 : padding);
int stride = (width * bytesPerPixel) + padding;
UInt32[] pixels = new UInt32[width * height];
GCHandle gchPixels = GCHandle.Alloc(pixels, GCHandleType.Pinned);
using (Bitmap bmp = new Bitmap(width, height, stride, PixelFormat.Format32bppPArgb, gchPixels.AddrOfPinnedObject()))
{
for (int y = 0; y < height; y++)
{
int row = (y * width);
for (int x = 0; x < width; x++)
{
pixels[row + x] = (uint)r.Next();
}
}
bmp.Save(@"c:\test.jpg", ImageFormat.Jpeg);
}
gchPixels.Free();