九色国产,午夜在线视频,新黄色网址,九九色综合,天天做夜夜做久久做狠狠,天天躁夜夜躁狠狠躁2021a,久久不卡一区二区三区

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
C#中保存GIF文件后透明背景問題的一個解決方法

  以前在用C#做網(wǎng)站保存縮略圖的程序中發(fā)現(xiàn),當(dāng)保存為GIF文件類型時,原來的透明背景變成了黑色,當(dāng)時由于趕時間,就統(tǒng)一用白色代替了背景,并用Jpeg格式存儲,并沒有深究。

  近來在網(wǎng)上查閱了許多資料,看到了兩種解決方法:一種是在顯示時設(shè)置透明背景色,GIF文件本身并不改變,另一種是不推薦使用的調(diào)用API的方法。將后一種I的VB源碼用C#重寫后,發(fā)現(xiàn)其中的調(diào)色板設(shè)置太少,轉(zhuǎn)換效果不理想。

  重新到網(wǎng)上搜索關(guān)于調(diào)色板的資料,發(fā)現(xiàn)MSDN上的一篇《對 ASP.NET 圖像的顏色量化(Quantization)進(jìn)行優(yōu)化》的文章。

http://www.microsoft.com/china/MSDN/library/archives/library/DNAspp/html/colorquant.asp

  將其中基于調(diào)色板量化的代碼分離出來,透明背景色的圖片保存成功。

  完整代碼如下:

using System;
using System.Collections;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;

namespace WindwoodGif
{
public class GifPalette
{
private static ArrayList _cardPalette;
private Color[] _colors;
private Hashtable _colorMap;

public GifPalette(ArrayList palette)
{
_colorMap
= new Hashtable();
_colors
= new Color[palette.Count];
palette.CopyTo(_colors);
}


public GifPalette()
{
ArrayList palette
= SetPalette();
_colorMap
= new Hashtable();
_colors
= new Color[palette.Count];
palette.CopyTo(_colors);
}


public Bitmap Quantize(Image source)
{
int height = source.Height;
int width = source.Width;

Rectangle bounds
= new Rectangle(0, 0, width, height);

Bitmap copy
= new Bitmap(width, height, PixelFormat.Format32bppArgb);
Bitmap output
= new Bitmap(width, height, PixelFormat.Format8bppIndexed);

using (Graphics g = Graphics.FromImage(copy))
{
g.PageUnit
= GraphicsUnit.Pixel;

g.DrawImageUnscaled(source, bounds);
}


BitmapData sourceData
= null;

try
{
sourceData
= copy.LockBits(bounds, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);

output.Palette
= this.GetPalette(output.Palette);

SecondPass(sourceData, output, width, height, bounds);
}

finally
{
copy.UnlockBits(sourceData);
}


return output;
}


private ColorPalette GetPalette(ColorPalette palette)
{
for (int index = 0; index < _colors.Length; index++)
palette.Entries[index]
= _colors[index];
return palette;
}


private unsafe void SecondPass(BitmapData sourceData, Bitmap output, int width, int height, Rectangle bounds)
{
BitmapData outputData
= null;

try
{
outputData
= output.LockBits(bounds, ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);

byte* pSourceRow = (byte*)sourceData.Scan0.ToPointer();
Int32
* pSourcePixel = (Int32*)pSourceRow;
Int32
* pPreviousPixel = pSourcePixel;

byte* pDestinationRow = (byte*)outputData.Scan0.ToPointer();
byte* pDestinationPixel = pDestinationRow;

byte pixelValue = QuantizePixel((Color32*)pSourcePixel);

*pDestinationPixel = pixelValue;

for (int row = 0; row < height; row++)
{
pSourcePixel
= (Int32*)pSourceRow;

pDestinationPixel
= pDestinationRow;

for (int col = 0; col < width; col++, pSourcePixel++, pDestinationPixel++)
{
if (*pPreviousPixel != *pSourcePixel)
{
pixelValue
= QuantizePixel((Color32*)pSourcePixel);

pPreviousPixel
= pSourcePixel;
}


*pDestinationPixel = pixelValue;
}


pSourceRow
+= sourceData.Stride;

pDestinationRow
+= outputData.Stride;
}

}

finally
{
output.UnlockBits(outputData);
}

}


private unsafe byte QuantizePixel(Color32* pixel)
{
byte colorIndex = 0;
int colorHash = pixel->ARGB;

if (_colorMap.ContainsKey(colorHash))
colorIndex
= (byte)_colorMap[colorHash];
else
{
if (0 == pixel->Alpha)
{
for (int index = 0; index < _colors.Length; index++)
{
if (0 == _colors[index].A)
{
colorIndex
= (byte)index;
break;
}

}

}

else
{
int leastDistance = int.MaxValue;
int red = pixel->Red;
int green = pixel->Green;
int blue = pixel->Blue;

for (int index = 0; index < _colors.Length; index++)
{
Color paletteColor
= _colors[index];

int redDistance = paletteColor.R - red;
int greenDistance = paletteColor.G - green;
int blueDistance = paletteColor.B - blue;

int distance = (redDistance * redDistance) +
(greenDistance
* greenDistance) +
(blueDistance
* blueDistance);

if (distance < leastDistance)
{
colorIndex
= (byte)index;
leastDistance
= distance;

if (0 == distance)
break;
}

}

}


_colorMap.Add(colorHash, colorIndex);
}


return colorIndex;
}


[StructLayout(LayoutKind.Explicit)]
public struct Color32
{
[FieldOffset(
0)]
public byte Blue;

[FieldOffset(
1)]
public byte Green;

[FieldOffset(
2)]
public byte Red;

[FieldOffset(
3)]
public byte Alpha;

[FieldOffset(
0)]
public int ARGB;

public Color Color
{
get { return Color.FromArgb(Alpha, Red, Green, Blue); }
}

}


public static ArrayList SetPalette()
{
if (null == _cardPalette)
{
_cardPalette
= new ArrayList();

Insert the colors into the arraylist
}

return _cardPalette;
}


}

}

  調(diào)用方法:

  先將該類添加到項(xiàng)目中,再在合適的地方調(diào)用。例:

Bitmap bitmap = new System.Drawing.Bitmap(width, height); // Image類也可
// ......(圖形操作代碼)
WindwoodGif.GifPalette gifPalette = new WindwoodGif.GifPalette();
bitmap = gifPalette.Quantize(bitmap);
bitmap.Save(SaveFileName, ImageFormat.Gif);

  經(jīng)測試,這種方法能夠?qū)崿F(xiàn)GIF文件的透明背景存儲,在WinForm、WebForm均能使用。由于使用了標(biāo)準(zhǔn)256色調(diào)色板,內(nèi)存開銷可能較大,轉(zhuǎn)換時間相對較慢,圖像質(zhì)量也有一定影響。此外,代碼中使用了非安全代碼(指針),在編譯時項(xiàng)目屬性中要設(shè)置允許不安全代碼。

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
降低顏色深度及調(diào)色板處理
bitmap的圖像像素遍歷方法
Taking a look at SWT Images
.NET Core 生成二維碼
【C#】加快Bitmap的訪問速度
c#的圖片合成
更多類似文章 >>
生活服務(wù)
熱點(diǎn)新聞
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服