将纹理应用于位图






3.96/5 (20投票s)
2003年8月31日

92475
展示如何将纹理应用于位图。
引言
我觉得这段代码可能对某人有用。我基本上是从 VBForums 论坛上的某个帖子(我自己的帖子)复制粘贴过来的。我的做法是:我将纹理转换为灰度。最白的像素(最高的 r、g 或 b 值)将具有最大的透明度。最暗的像素在应用纹理时将具有最小的透明度。
我的代码在技术上可能不正确,或者不是执行此操作的最有效方法。我只是想分享如何应用纹理的想法。希望这有帮助。
详细说明
调用 ApplyTexture()
将纹理应用于您的位图。这是代码
' REMEMBER to add this to the class file that contains
' this code: Imports System.Drawing.Imaging
' Modifies the ORIGINAL bitmap
' textureTransparency has to be between 0 and 1,
' with 0 being the least transparent, and 1 the most transparent
Public Shared Sub ApplyTexture(ByRef bmp As Bitmap, _
ByVal texture As Bitmap, _
ByVal textureTransparency As Single)
If (bmp Is Nothing) OrElse (texture Is Nothing) _
Then Throw New ArgumentNullException
If textureTransparency < 0 OrElse textureTransparency > 1 Then
Throw New ArgumentOutOfRangeException( _
"textureTransparency must be between 0 and 1.")
End If
' Convert the texture to grayscale before using it
MakeImageGrayscale(texture)
Dim x, y, alpha As Integer
' Adjust the alpha value of each pixel in the texture bitmap.
' The white-most pixels will have the the
' most transparency (highest alpha),
' and the dark-most pixels will have the least transparency.
For x = 0 To texture.Width - 1
For y = 0 To texture.Height - 1
Dim c As Color = texture.GetPixel(x, y)
' c.R -> all of the RGB values are the same
' since the image is in grayscale
alpha = CInt(c.R * textureTransparency)
c = Color.FromArgb(alpha, c)
texture.SetPixel(x, y, c)
Next
Next
Dim gr As Graphics = Graphics.FromImage(bmp)
Dim myBrush As New TextureBrush(texture)
' Draw the texture over the original bitmap
gr.FillRectangle(myBrush, bmp.GetBounds(GraphicsUnit.Pixel))
myBrush.Dispose()
gr.Dispose()
End Sub
' Converts the image to grayscale
Public Shared Sub MakeImageGrayscale(ByVal bmp As Bitmap)
Dim cMatrix As New ColorMatrix(New Single()() _
{New Single() {0.299, 0.299, 0.299, 0, 0}, _
New Single() {0.587, 0.587, 0.587, 0, 0}, _
New Single() {0.114, 0.114, 0.114, 0, 0}, _
New Single() {0, 0, 0, 1, 0}, _
New Single() {0, 0, 0, 0, 1}})
Dim imageAttrib As New ImageAttributes
imageAttrib.SetColorMatrix(cMatrix)
Dim gr As Graphics = Graphics.FromImage(bmp)
' Apply the grayscale image attribute
gr.DrawImage(bmp, New Rectangle(0, 0, bmp.Width, bmp.Height), _
0, 0, bmp.Width, bmp.Height, GraphicsUnit.Pixel, imageAttrib)
gr.Dispose()
End Sub
我不知道如何用 C# 编程,但我设法将其转换为 C# 并使用指针代替 SetPixel
和 GetPixel
。我使用了 Christian Graus 在 CodeProject 上的一篇文章来了解如何使用指针读取位图的 RGB 数据,并对其进行了一些修改以读取 ARGB 值。我希望我做的一切都正确:)
这就是它,比 VB 版本更快
// REMEMBER to add this to the class file that contains your code
// using System.Drawing.Imaging;
// Modifies the ORIGINAL bitmap
// textureTransparency has to be between 0 and 1,
// with 0 being the least transparent, and 1 the most transparent
public static void ApplyTexture (Image img, Image texture,
float textureTransparency)
{
if ( (img ==null) || (texture==null) )
throw new ArgumentNullException();
if (textureTransparency < 0 || textureTransparency > 1)
throw new ArgumentOutOfRangeException(
"Value must be between 0 and 1.");
// Convert the texture to grayscale before using it
MakeImageGrayscale (texture);
Bitmap txtr = new Bitmap(texture);
BitmapData bmData = txtr.LockBits(new Rectangle(0, 0,
txtr.Width, txtr.Height),
ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
int stride = bmData.Stride;
System.IntPtr Scan0 = bmData.Scan0;
// Adjust the alpha value of each pixel in the texture bitmap.
// The white-most pixels will have the the
// most transparency (highest alpha),
// and the dark-most pixels will have the least transparency.
unsafe
{
byte * p = (byte *)(void *)Scan0;
int nOffset = stride - txtr.Width*4;
for (int y=0; y < txtr.Height; ++y)
{
for (int x=0; x < txtr.Width; ++x)
{
// p[3] is alpha - array is BGRA (blue, green ,
// red, alpha)
p[3] = (byte)(p[0] * textureTransparency);
p += 4; // Move to the next pixel
}
p += nOffset;
}
}
txtr.UnlockBits(bmData);
Graphics gr = Graphics.FromImage(img);
TextureBrush myBrush = new TextureBrush(txtr);
gr.FillRectangle (myBrush,0,0,img.Width, img.Height);
myBrush.Dispose();
gr.Dispose();
txtr.Dispose();
}
// Converts the image to grayscale
public static void MakeImageGrayscale (Image img)
{
ColorMatrix cMatrix = new ColorMatrix (
new float[][] {
new float[] {0.299F, 0.299F, 0.299F, 0, 0},
new float[] {0.587F, 0.587F, 0.587F, 0, 0},
new float[] {0.114F, 0.114F, 0.114F, 0, 0},
new float[] {0, 0, 0, 1, 0},
new float[] {0, 0, 0, 1, 0}});
ImageAttributes imageAttrib = new ImageAttributes();
imageAttrib.SetColorMatrix(cMatrix);
Graphics gr = Graphics.FromImage (img);
// Apply the grayscale image attribute
gr.DrawImage (img, new Rectangle(0, 0, img.Width, img.Height),
0, 0, img.Width, img.Height, GraphicsUnit.Pixel,
imageAttrib);
gr.Dispose();
}
感谢 Greg Ingelmo 指正我:)