我需要将自定义形状(this,.jpg)应用到我加载到我的应用程序中的任何图像,如果可能的话使用Windows窗体(因为我的整个项目是在Winforms中制作的),但我想我如果需要,可以使用WPF。
例如,如果我有像this这样的照片,结果应该像this(我用Photoshop制作这个就可以看到),如果可能的话甚至可能没有白色边框(请请注意,图像已调整大小并居中以适应自定义形状,以及它应该如何)。
我无法弄清楚如何做到这一点,但从我搜索的内容来看,我认为它与画笔(TextureBrush,ImageBrush等)有关。
问候。
答案 0 :(得分:1)
在我看来,你想要应用一个掩码,你可以用这样的东西(使用/不安全的代码)来做:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace testImageBlender
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
Bitmap imBase;
Bitmap imMask,imMask2;
Bitmap blendedImage;
private void Form1_Load(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
if (openFileDialog2.ShowDialog() == DialogResult.OK)
{
imBase = new Bitmap(openFileDialog1.FileName);
imMask = new Bitmap(openFileDialog2.FileName);
blendedImage = new Bitmap(openFileDialog2.FileName);
blendImage();
}
}
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
if (imBase != null)
{
if (imMask != null)
{
if (blendedImage != null)
{
e.Graphics.DrawImage(blendedImage, e.ClipRectangle);
}
}
}
}
private void blendImage()
{
Rectangle mRec = new Rectangle(0, 0, imMask.Width, imMask.Height);
float intensity = 0;
//playing around with images to get pixel format 24bpp RGB, most probably a very bad way of doing it, but I don't know enough about image format and lockbits to do it nice and clean yet
imMask2 = new Bitmap(imMask);
Graphics.FromImage(imBase).DrawImage(imBase, 0, 0, imMask.Width, imMask.Height);
Graphics.FromImage(blendedImage).DrawImage(imMask, 0, 0, imMask.Width, imMask.Height);
Graphics.FromImage(imMask2).DrawImage(imMask, 0, 0, imMask.Width, imMask.Height);
BitmapData imageData = imBase.LockBits(mRec, ImageLockMode.ReadOnly, imBase.PixelFormat);
BitmapData maskData = imMask2.LockBits(mRec, ImageLockMode.ReadOnly, imMask.PixelFormat);
BitmapData blendedData = blendedImage.LockBits(mRec, ImageLockMode.WriteOnly, blendedImage.PixelFormat);
unsafe
{
byte* imagePointer = (byte*)imageData.Scan0;
byte* maskPointer = (byte*)maskData.Scan0;
byte* blendedPointer = (byte*)blendedData.Scan0;
for (int i = 0; i < mRec.Height; i++)
{
for (int j = 0; j < mRec.Width; j++)
{
intensity = 1-((float)(maskPointer[0] + maskPointer[1] + maskPointer[2])) / ((float)3 * 255);
for (int k = 0; k < 3; k++)
{
blendedPointer[k] = (intensity>0.8)?(byte)((float)imagePointer[k]):(byte)255;
}
// 3 bytes per pixel
imagePointer += 3;
maskPointer += 3;
blendedPointer += 3;
}
// Moving the pointers to the next pixel row
imagePointer += imageData.Stride - (mRec.Width * 3);
maskPointer += maskData.Stride - (mRec.Width * 3);
blendedPointer += blendedData.Stride - (mRec.Width * 3);
}
}
imBase.UnlockBits(imageData);
imMask2.UnlockBits(maskData);
blendedImage.UnlockBits(blendedData);
}
}
}
这很受Balazs Tihanyi在Draw image on top of another image with blending mode color
的回答的启发答案 1 :(得分:0)
以下是针对image you linked to调整的示例:
using (var source = (Bitmap) Image.FromFile(@"image filename"))
{
using (var target = new Bitmap(source.Width, source.Height))
{
using (var graphics = Graphics.FromImage(target))
{
using (var path = new GraphicsPath())
{
path.StartFigure();
path.AddLine(161, 665, 223, 624);
path.AddLine(223, 624, 252, 568);
path.AddLine(252, 568, 239, 525);
path.AddLine(239, 525, 200, 432);
path.AddLine(200, 432, 178, 343);
path.AddLine(178, 343, 156, 198);
path.AddLine(156, 198, 161, 131);
path.AddLine(161, 131, 248, 38);
path.AddLine(248, 38, 366, 4);
path.AddLine(366, 4, 657, 10);
path.AddLine(657, 10, 735, 70);
path.AddLine(735, 70, 741, 195);
path.AddLine(741, 195, 746, 282);
path.AddLine(746, 282, 762, 410);
path.AddLine(762, 410, 730, 498);
path.AddLine(730, 498, 686, 582);
path.AddLine(686, 582, 727, 669);
path.CloseFigure();
graphics.Clip = new Region(path);
}
graphics.DrawImage(source, 0, 0);
}
this.PictureBox.Image = new Bitmap(target);
}
}