C# Image转变Bitmap时候出现变异。
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C# Image转变Bitmap时候出现变异。相关的知识,希望对你有一定的参考价值。
private void button1_Click(object sender, EventArgs e) if (openFileDialog1.ShowDialog() == DialogResult.OK) filename = openFileDialog1.FileName; pictureBox1.Image = Image.FromFile(filename); private void button2_Click(object sender, EventArgs e) //g_bm_bitmap = (Bitmap)Image.FromFile(filename); g_bm_bitmap = new Bitmap(Image.FromFile(filename)); Bitmap second = g_bm_bitmap; pictureBox1.Image = g_bm_bitmap;从Image转换bitmap的时候显示bitmap发现和原先的不同了,黑色区域突然变出很多红色点。。。求解答。。。。
http://pan.baidu.com/s/1qY6CmVa
谢谢各位哦
http://pan.baidu.com/s/1qY6CmVa
参考技术A 共享项目源码来调试。C#如何在不使用大量内存的情况下裁剪图像? [复制]
【中文标题】C#如何在不使用大量内存的情况下裁剪图像? [复制]【英文标题】:C# How to crop an image without using lots of memory? [duplicate] 【发布时间】:2012-11-23 15:23:05 【问题描述】:可能重复:How to crop huge image
有个问题问如何裁剪图片here
我已经阅读并使用了答案。但它们似乎都需要将图像加载到Bitmap
或Image
。
这导致我出现内存问题。当我试图将 5 张图像 (8000 x 8000) 裁剪成图块时。一次一个。
如果我错了,请纠正我,但那是 8000x8000x4 字节 = 244 MB。每张图片。
我随机出现内存不足的问题。
如何从另一个图像中获取 1000x1000 的图像,同时减少内存消耗。
【问题讨论】:
您想裁剪图像而不将其加载到内存中?为什么你必须同时处理所有 5 张图像?处理一个,关闭它,然后处理另一个。 您的内存不足问题可能与您的代码有关。你能告诉我们你用来裁剪图像的代码吗? 不幸的是 .NET 没有办法只加载图像的一小部分。 这是什么平台/类?我知道一些平台(Silverlight、Unity3D)可以使用比每个像素 4 个字节更多的内存。 @Tibi。这正是我想要做的:p。以编程方式将图像拆分为图块。图像最终出现在 android 上(每像素 4 个字节,~24MB 内存余量)。问题是桌面也有/可能有内存限制。 (不要尝试使用整个位图,因为有人似乎认为重复 - 而其他裁剪图像“答案”是 10 分钟前)。 【参考方案1】:因此,这绝对是一件非常重要的事情 - 基本上,您必须为给定的图像格式重新实现图像解码器。这不简单。
对于“简单”的 Windows BMP 格式,有这些野兽要与之抗衡:
BMP File Format DIB Header Structure也就是说,我必须在午休时试一试……这是我能想到的,用一个漂亮的 LINQPad 就绪脚本。
(注意:仅限 Windows BMP!)
void Main()
// Carve out a 100x100 chunk
var top = 100;
var left = 100;
var bottom = 300;
var right = 300;
// For BMP only - open input
var fs = File.OpenRead(@"c:\temp\testbmp.bmp");
// Open output
if(File.Exists(@"c:\temp\testbmp.cropped.bmp")) File.Delete(@"c:\temp\testbmp.cropped.bmp");
var output = File.Open(@"c:\temp\testbmp.cropped.bmp", FileMode.CreateNew);
var bw = new BinaryWriter(output);
// Read out the BMP header fields
var br = new BinaryReader(fs);
var headerField = br.ReadInt16();
var bmpSize = br.ReadInt32();
var reserved1 = br.ReadInt16();
var reserved2 = br.ReadInt16();
var startOfData = br.ReadInt32();
// Read out the BMP DIB header
var header = new BITMAPV5Header();
var headerBlob = br.ReadBytes(Marshal.SizeOf(header));
var tempMemory = Marshal.AllocHGlobal(Marshal.SizeOf(header));
Marshal.Copy(headerBlob, 0, tempMemory, headerBlob.Length);
header = (BITMAPV5Header)Marshal.PtrToStructure(tempMemory, typeof(BITMAPV5Header));
Marshal.FreeHGlobal(tempMemory);
// This file is a 24bpp rgb bmp,
var format = PixelFormats.Bgr24;
var bytesPerPixel = (int)(format.BitsPerPixel / 8);
Console.WriteLine("Bytes/pixel:0", bytesPerPixel);
// And now I know its dimensions
var imageWidth = header.ImageWidth;
var imageHeight = header.ImageHeight;
Console.WriteLine("Input image is:0x1", imageWidth, imageHeight);
var fromX = left;
var toX = right;
var fromY = imageHeight - top;
var toY = imageHeight - bottom;
// How "long" a horizontal line is
var strideInBytes = imageWidth * bytesPerPixel;
Console.WriteLine("Stride size is:0x0:x", strideInBytes);
// new size
var newWidth = Math.Abs(toX - fromX);
var newHeight = Math.Abs(toY - fromY);
Console.WriteLine("New slice dimensions:0x1", newWidth, newHeight);
// Write out headers to output file
// header = "BM" = "Windows Bitmap"
bw.Write(Encoding.ASCII.GetBytes("BM"));
var newSize = 14 + Marshal.SizeOf(header) + (newWidth * newHeight * bytesPerPixel);
Console.WriteLine("New File size: 0x0:x bytes", newSize);
bw.Write((uint)newSize);
// 2 reserved shorts
bw.Write((ushort)0);
bw.Write((ushort)0);
// offset to "data"
bw.Write(header.HeaderSize + 14);
// Tweak size in header to cropped size
header.ImageWidth = newWidth;
header.ImageHeight = newHeight;
// Write updated DIB header to output
tempMemory = Marshal.AllocHGlobal(Marshal.SizeOf(header));
Marshal.StructureToPtr(header, tempMemory, true);
byte[] asBytes = new byte[Marshal.SizeOf(header)];
Marshal.Copy(tempMemory, asBytes, 0, asBytes.Length);
Marshal.FreeHGlobal(tempMemory);
bw.Write(asBytes);
asBytes.Dump();
// Jump to where the pixel data is located (on input side)
Console.WriteLine("seeking to position: 0x0:x", startOfData);
fs.Seek(startOfData, SeekOrigin.Begin);
var sY = Math.Min(fromY, toY);
var eY = Math.Max(fromY, toY);
for(int currY = sY; currY < eY; currY++)
long offset = startOfData + ((currY * strideInBytes) + (fromX * bytesPerPixel));
fs.Seek(offset, SeekOrigin.Begin);
// Blast in each horizontal line of our chunk
var lineBuffer = new byte[newWidth * bytesPerPixel];
int bytesRead = fs.Read(lineBuffer, 0, lineBuffer.Length);
output.Write(lineBuffer, 0, lineBuffer.Length);
fs.Close();
output.Close();
[StructLayout(LayoutKind.Sequential, Pack=0)]
public struct BITMAPV5Header
public uint HeaderSize;
public int ImageWidth;
public int ImageHeight;
public ushort Planes;
public ushort BitCount;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=36)]
public byte[] DontCare;
【讨论】:
+1 只是为了展示它的复杂程度,仅适用于单个文件类型。不幸的是,我需要使用一些文件类型。以上是关于C# Image转变Bitmap时候出现变异。的主要内容,如果未能解决你的问题,请参考以下文章
java将base64转换成图片并保存在指定路径下ImageIO.write(bi1,"png",w2)提示image==null