覆盖图片框纹理和结构

时间:2014-10-05 13:40:19

标签: c# image visual-studio-2012 overlay

我有一个矩形形状,其中我有一个带有图片的图片框组件: Idk

我想在不破坏轮廓的情况下更改图片纹理: enter image description here

我无法在编辑器中创建图像,因为我有许多图像和许多纹理,它不会有效。我知道它可以在Visual Studio中完成,我不认为它是用不透明度完成的(它会更亮或者轮廓不那么明显。感谢您提前的时间!

1 个答案:

答案 0 :(得分:3)

你需要一个例程,将结构的亮度乘以纹理的颜色。

这是一个:

public static Bitmap Multiply(Bitmap bmp0, Bitmap bmp1)
{
    int Bpp = 4;  // assuming an effective pixelformat of 32bpp

    var bmpData0 = bmp0.LockBits(
                    new Rectangle(0, 0, bmp0.Width, bmp0.Height),
                    ImageLockMode.ReadWrite, bmp0.PixelFormat);
    var bmpData1 = bmp1.LockBits(
                    new Rectangle(0, 0, bmp1.Width, bmp1.Height),
                    ImageLockMode.ReadOnly, bmp1.PixelFormat);

    int len = bmpData0.Height * bmpData0.Stride;
    byte[] data0 = new byte[len];
    byte[] data1 = new byte[len];
    Marshal.Copy(bmpData0.Scan0, data0, 0, len);
    Marshal.Copy(bmpData1.Scan0, data1, 0, len);

    float brighter =  1.3f;
    for (int i = 0; i < len; i += Bpp)
    {
        //float h = (data1[i] + data1[i + 1] + data1[i + 2]) / (255 * 3f);
        // assuming a grayscale structure overlay:
        float h = data1[i] / 255f;
        h *= brighter;    
        data0[i]     = (byte)(Math.Min(255, (data0[i] * h)));
        data0[i + 1] = (byte)(Math.Min(255, (data0[i + 1] * h)));
        data0[i + 2] = (byte)(Math.Min(255, (data0[i + 2] * h)));
        if (Bpp == 4) data0[i + 3] = 255;   // shouldn't be necessary
    }
    Marshal.Copy(data0, 0, bmpData0.Scan0, len);
    bmp0.UnlockBits(bmpData0);
    bmp1.UnlockBits(bmpData1);
    return bmp0;
}

它会产生一些分歧:

  • 两张图片尺寸相同
  • 两个图像都具有相同的有效像素格式
  • 第一个图像是纹理,第二个是结构
  • 结构为灰度。 (如果它未取消注释h
  • 的设置

注意:

  • 令我惊讶的是,我发现即使IrfanView报告源图像是24bpp,当例程与它们一起工作时它们也是32bpp。看起来默认情况下,GDI +会将每个PNG转换为32bpp
  • 例程仅使用结构图的一个通道。如果是彩色图像,您可能需要更改h的计算。使用所有3个频道的频道并不能计算出感知亮度,但这应该是为了这个目的。
  • 由于结构的主体不是白色,因此总体结果比原始图案稍暗。我添加了一个修正系数brighter以稍微调整h和将字节限制为255的代码。不要使brighter太大或结构的灯光将会迷路..

以下是如何使用它:

string structure = @"d:\structure_01.png";
string pattern   = @"d:\pat_01.png";

// cleanup old bitmap!
if (pictureBox1.Image != null) pictureBox1.Image.Dispose();

using ( Bitmap bm1 = new Bitmap(structure) )
{
    Bitmap bm0 = new Bitmap(pattern);
    pictureBox1.Image = Multiply(bm0, bm1);
}

以下是两个源图像和结果:

texture structure overlay