在 .NET C# 程序中,我们可以使用 GDI+(Graphics Device Interface)来对图像进行操作。GDI+ 是 Microsoft Windows 操作系统的一个组件,提供了一组用于绘制图形、图像和文本的 API。
为了向图片中添加浮雕效果,我们需要做以下几个步骤:
1. 加载图片
我们可以使用 Image.FromFile() 方法从文件中加载图片,也可以从其他来源如流、URL 中加载。示例代码如下:
Image img = Image.FromFile("image.jpg");
2. 创建 Graphics 对象
我们需要创建一个 Graphics 对象来对图片进行操作。Graphics 对象在绘制图形时提供了多种方法和属性。我们可以使用 Graphics.FromImage() 方法来创建 Graphics 对象。示例代码如下:
Graphics g = Graphics.FromImage(img);
3. 创建模糊和锐化滤镜
我们可以使用 GDI+ 的 Blur 和 Sharpen 滤镜来增强浮雕效果。这里以 Sharpness 滤镜为例,它可以增强图像的锐度。示例代码如下:
Bitmap blurredImage = new Bitmap(img);
Bitmap sharpenedImage = new Bitmap(img);
// 模糊
using (Graphics graphics = Graphics.FromImage(blurredImage))
{
Rectangle rectangle = new Rectangle(0, 0, blurredImage.Width, blurredImage.Height);
graphics.DrawImage(blurredImage, rectangle, rectangle, GraphicsUnit.Pixel);
Blur(blurredImage, rectangle, 10);
}
// 锐化
using (Graphics graphics = Graphics.FromImage(sharpenedImage))
{
Rectangle rectangle = new Rectangle(0, 0, sharpenedImage.Width, sharpenedImage.Height);
graphics.DrawImage(sharpenedImage, rectangle, rectangle, GraphicsUnit.Pixel);
Sharpen(sharpenedImage, rectangle, 10);
}
其中,Blur 和 Sharpen 方法的实现可以在下面找到。
4. 叠加原图和滤镜图
我们可以使用 Graphics 对象的 DrawImageUnscaled() 方法叠加原图和滤镜图,从而增强浮雕效果。示例代码如下:
g.DrawImageUnscaled(blurredImage, 0, 0);
g.DrawImageUnscaled(sharpenedImage, 0, 0);
5. 保存图片
最后我们将修改后的图片保存到磁盘中。示例代码如下:
img.Save("new_image.jpg", ImageFormat.Jpeg);
完整的代码如下:
using System.Drawing;
using System.Drawing.Imaging;
private void Blur(Bitmap a, Rectangle rectangle, int blurSize)
{
Bitmap blurredBitmap = new Bitmap(a.Width, a.Height);
for (int xx = rectangle.X; xx < rectangle.X + rectangle.Width; xx++)
{
for (int yy = rectangle.Y; yy < rectangle.Y + rectangle.Height; yy++)
{
int avgR = 0, avgG = 0, avgB = 0;
int blurPixelCount = 0;
// 取周围 2*blurSize 个像素的平均值
for (int x = xx; (x < xx + blurSize && x < a.Width); x++)
{
for (int y = yy; (y < yy + blurSize && y < a.Height); y++)
{
Color pixel = a.GetPixel(x, y);
avgR += pixel.R;
avgG += pixel.G;
avgB += pixel.B;
blurPixelCount++;
}
}
avgR /= blurPixelCount;
avgG /= blurPixelCount;
avgB /= blurPixelCount;
// 设置像素值
for (int x = xx; x < xx + blurSize && x < a.Width; x++)
for (int y = yy; y < yy + blurSize && y < a.Height; y++)
blurredBitmap.SetPixel(x, y, Color.FromArgb(avgR, avgG, avgB));
}
}
Graphics g = Graphics.FromImage(a);
Rectangle imageRectangle = new Rectangle(rectangle.Location, rectangle.Size);
g.DrawImage(blurredBitmap, imageRectangle, imageRectangle, GraphicsUnit.Pixel);
}
private void Sharpen(Bitmap a, Rectangle rectangle, int weight)
{
Bitmap sharpenedBitmap = new Bitmap(a.Width, a.Height);
int filterWidth = 3;
int filterHeight = 3;
int[,] filter = new int[filterWidth, filterHeight];
filter[0, 0] = filter[0, 1] = filter[0, 2] = filter[1, 0] = filter[1, 2] = filter[2, 0] = filter[2, 1] = filter[2, 2] = -1;
filter[1, 1] = weight * 8;
int bias = 0;
// 灰度化
Color[,] grayPixels = new Color[a.Width, a.Height];
for (int i = 0; i < a.Width; i++)
for (int j = 0; j < a.Height; j++)
{
Color c = a.GetPixel(i, j);
grayPixels[i, j] = Color.FromArgb((int)(0.299 * c.R + 0.587 * c.G + 0.114 * c.B),
(int)(0.299 * c.R + 0.587 * c.G + 0.114 * c.B),
(int)(0.299 * c.R + 0.587 * c.G + 0.114 * c.B));
}
// 卷积
for (int x = filterWidth / 2; x < a.Width - filterWidth / 2; x++)
{
for (int y = filterHeight / 2; y < a.Height - filterHeight / 2; y++)
{
int r = 0, g = 0, b = 0;
for (int filterX = 0; filterX < filterWidth; filterX++)
{
for (int filterY = 0; filterY < filterHeight; filterY++)
{
int imageX = x - filterWidth / 2 + filterX;
int imageY = y - filterHeight / 2 + filterY;
Color imagePixel = grayPixels[imageX, imageY];
r += imagePixel.R * filter[filterX, filterY];
g += imagePixel.G * filter[filterX, filterY];
b += imagePixel.B * filter[filterX, filterY];
}
}
r = Math.Min(Math.Max((r / weight) + bias, 0), 255);
g = Math.Min(Math.Max((g / weight) + bias, 0), 255);
b = Math.Min(Math.Max((b / weight) + bias, 0), 255);
Color resultColor = Color.FromArgb(r, g, b);
sharpenedBitmap.SetPixel(x, y, resultColor);
}
}
Graphics g = Graphics.FromImage(a);
Rectangle imageRectangle = new Rectangle(rectangle.Location, rectangle.Size);
g.DrawImage(sharpenedBitmap, imageRectangle, imageRectangle, GraphicsUnit.Pixel);
}
// 加载图片
Image img = Image.FromFile("image.jpg");
// 创建 Graphics 对象
Graphics g = Graphics.FromImage(img);
// 创建滤镜
Bitmap blurredImage = new Bitmap(img);
Bitmap sharpenedImage = new Bitmap(img);
using (Graphics graphics = Graphics.FromImage(blurredImage))
{
Rectangle rectangle = new Rectangle(0, 0, blurredImage.Width, blurredImage.Height);
graphics.DrawImage(blurredImage, rectangle, rectangle, GraphicsUnit.Pixel);
Blur(blurredImage, rectangle, 10);
}
using (Graphics graphics = Graphics.FromImage(sharpenedImage))
{
Rectangle rectangle = new Rectangle(0, 0, sharpenedImage.Width, sharpenedImage.Height);
graphics.DrawImage(sharpenedImage, rectangle, rectangle, GraphicsUnit.Pixel);
Sharpen(sharpenedImage, rectangle, 10);
}
// 叠加原图和滤镜图
g.DrawImageUnscaled(blurredImage, 0, 0);
g.DrawImageUnscaled(sharpenedImage, 0, 0);
// 保存图片
img.Save("new_image.jpg", ImageFormat.Jpeg);
``
以上是思路和代码,但过复杂,这里有一个简单的代码
Bitmap myBitmap =UF.Properties.Resources.img;
for (int i = 0; i < myBitmap.Width - 1; i++)
{
for (int j = 0; j < myBitmap.Height - 1; j++)
{
Color Color1 = myBitmap.GetPixel(i, j);
Color Color2 = myBitmap.GetPixel(i + 1, j + 1);
int red = Math.Abs(Color1.R - Color2.R + 128);
int green = Math.Abs(Color1.G - Color2.G + 128);
int blue = Math.Abs(Color1.B - Color2.B + 128);
//颜色处理
if (red > 255) red = 255;
if (red < 0) red = 0;
if (green > 255) green = 255;
if (green < 0) green = 0;
if (blue > 255) blue = 255;
if (blue < 0) blue = 0;
myBitmap.SetPixel(i, j, Color.FromArgb(red, green, blue));
}
}
this.BackgroundImage = myBitmap;
效果如下: