C#合并BitMap圖像生成超大bitmap
當(dāng)只需要兩個(gè)圖像合并的時(shí)候,可以簡(jiǎn)單的使用gdi+,把兩個(gè)圖像畫(huà)到一個(gè)畫(huà)布上面實(shí)現(xiàn)合并bitmap.
當(dāng)需要將許多bitmap合并時(shí),由于bitmap類(lèi)限制,長(zhǎng)度或?qū)挾忍髸r(shí)會(huì)報(bào)異常,前面這種方法就行不通了。
由于bitmapp屬于位圖格式,了解圖像格式后,發(fā)現(xiàn),bitmap文件的第3-8位存儲(chǔ)了文件大小信息,第19-22位存儲(chǔ)了高度信息,第23-26位存儲(chǔ)了寬度信息。文件頭后面都是像素的argb,并無(wú)其它信息。于是,試想一下,如果把第二張圖像的像素argb放到第一張后面,并修改第一張的文件頭信息,是不是就可以實(shí)現(xiàn)文件合并了呢。事實(shí)證明:yes。
//設(shè)置文件頭里面文件大小信息
public void SetBitmapFileSizeInfo(string filePath)
{
FileInfo fileInfo = new FileInfo(filePath);
long le = fileInfo.Length;
string hexSize = le.ToString("X").PadLeft(8, '0');
int size1 = Convert.ToInt32(hexSize.Substring(0, 2), 16);
int size2 = Convert.ToInt32(hexSize.Substring(2, 2), 16);
int size3 = Convert.ToInt32(hexSize.Substring(4, 2), 16);
int size4 = Convert.ToInt32(hexSize.Substring(6, 2), 16);
byte[] sizeBytes = new byte[] { (byte)size4, (byte)size3, (byte)size2, (byte)size1 };
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Write))
{
using (BinaryWriter r = new BinaryWriter(fs))
{
r.Seek(2, 0);
r.Write(sizeBytes, 0, sizeBytes.Length);
}
}
}
設(shè)置文件頭里面文件長(zhǎng)度和寬度信息
public void SetBitmapSizeInfo(string filePath,int width=0,int height=0)
{
if (height != 0)
{
string hexHeight = height.ToString("X").PadLeft(8, '0');
int h1 = Convert.ToInt32(hexHeight.Substring(0, 2), 16);
int h2 = Convert.ToInt32(hexHeight.Substring(2, 2), 16);
int h3 = Convert.ToInt32(hexHeight.Substring(4, 2), 16);
int h4 = Convert.ToInt32(hexHeight.Substring(6, 2), 16);
byte[] sizeHeight = new byte[] { (byte)h4, (byte)h3, (byte)h2, (byte)h1 };
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite))
{
using (BinaryWriter r = new BinaryWriter(fs))
{
r.Seek(22, 0);//高度保存位置
r.Write(sizeHeight, 0, sizeHeight.Length);
}
}
}
if (width != 0)
{
string hexWidth = height.ToString("X").PadLeft(8, '0');
int w1 = Convert.ToInt32(hexWidth.Substring(0, 2), 16);
int w2 = Convert.ToInt32(hexWidth.Substring(2, 2), 16);
int w3 = Convert.ToInt32(hexWidth.Substring(4, 2), 16);
int w4 = Convert.ToInt32(hexWidth.Substring(6, 2), 16);
byte[] sizeWidth = new byte[] { (byte)w4, (byte)w3, (byte)w2, (byte)w1 };
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite))
{
using (BinaryWriter r = new BinaryWriter(fs))
{
r.Seek(18, 0);//高度保存位置
r.Write(sizeWidth, 0, sizeWidth.Length);
}
}
}
}
合并多個(gè)bitmap文件,并生成一個(gè)最終文件
private void CreateBitMap(string tempPath,string imagePath)
{
string[] files = Directory.GetFiles(tempPath, "*.png");
Bitmap bmp;
int height=0;
for (int i = files.Length-1; i >0; i--)
{
string fileName = files[i];
bmp = new Bitmap(fileName);
if (i == files.Length - 1)
{
bmp.Save(imagePath, ImageFormat.Bmp);
height += bmp.Height;
bmp.Dispose();
continue;
}
else
{
byte[] bytes = GetImageRasterBytes(bmp, PixelFormat.Format32bppRgb);
using (FileStream fs = new FileStream(imagePath, FileMode.Open, FileAccess.Write))
{
fs.Seek(fs.Length, 0);
fs.Write(bytes, 0, bytes.Length);
}
height += bmp.Height;
bmp.Dispose();
}
}
SetBitmapFileSizeInfo(imagePath);
SetBitmapSizeInfo(imagePath, height: height);
//MessageBox.Show("合并成功");
}
private static byte[] GetImageRasterBytes(Bitmap bmp, PixelFormat format)
{
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
byte[] bits = null;
try
{
// Lock the managed memory
BitmapData bmpdata = bmp.LockBits(rect, ImageLockMode.ReadWrite, format);
// Declare an array to hold the bytes of the bitmap.
bits = new byte[bmpdata.Stride * bmpdata.Height];
// Copy the values into the array.
System.Runtime.InteropServices.Marshal.Copy(bmpdata.Scan0, bits, 0, bits.Length);
// Release managed memory
bmp.UnlockBits(bmpdata);
}
catch
{
return null;
}
return bits;
}
到此這篇關(guān)于C#合并BitMap圖像生成超大bitmap的文章就介紹到這了,更多相關(guān)C#合并BitMap內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C#實(shí)體類(lèi)轉(zhuǎn)換的兩種方式小結(jié)
這篇文章主要介紹了C#實(shí)體類(lèi)轉(zhuǎn)換的兩種方式小結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-01-01
c#實(shí)現(xiàn)幾種數(shù)據(jù)庫(kù)的大數(shù)據(jù)批量插入
這篇文章主要介紹了c#實(shí)現(xiàn)幾種數(shù)據(jù)庫(kù)的大數(shù)據(jù)批量插入,主要包括SqlServer、Oracle、SQLite和MySQL,有興趣的可以了解一下。2017-01-01
基于WPF實(shí)現(xiàn)用戶(hù)頭像選擇器的示例代碼
這篇文章主要為大家詳細(xì)介紹了如何基于WPF實(shí)現(xiàn)用戶(hù)頭像選擇器,文中的示例代碼簡(jiǎn)潔易懂,對(duì)我們學(xué)習(xí)WPF有一定幫助,感興趣的可以了解一下2022-07-07

