C# 模仿这种成像效果
我在问这个问题,因为另一个已经两岁了,回答不准确。 我想复制C#中提到的PhotoShop效果。Adobe称之为彩色半色调,我认为它看起来像某种旋转的CMYK半色调。不管怎样,我都不知道该怎么做 下面是当前代码示例 有什么想法吗 附言 这不是家庭作业。我希望升级我在OSS项目中的漫画效果 进度更新。 所以这里有一些代码来显示我到目前为止所做的事情 我可以很容易地将CMYK转换成RGB,也可以根据一系列点上每个颜色分量的强度打印出一系列带图案的椭圆 我刚才遇到的问题是旋转每种颜色的图形对象,以便按代码中指定的角度放置点。谁能给我指点一下怎么做C# 模仿这种成像效果,c#,graphics,imageprocessor,C#,Graphics,Imageprocessor,我在问这个问题,因为另一个已经两岁了,回答不准确。 我想复制C#中提到的PhotoShop效果。Adobe称之为彩色半色调,我认为它看起来像某种旋转的CMYK半色调。不管怎样,我都不知道该怎么做 下面是当前代码示例 有什么想法吗 附言 这不是家庭作业。我希望升级我在OSS项目中的漫画效果 进度更新。 所以这里有一些代码来显示我到目前为止所做的事情 我可以很容易地将CMYK转换成RGB,也可以根据一系列点上每个颜色分量的强度打印出一系列带图案的椭圆 我刚才遇到的问题是旋转每种颜色的图形对象,以
公共图像处理图像(图像工厂)
{
位图newImage=null;
Image=factory.Image;
尝试
{
int-width=image.width;
int height=image.height;
//这些都需要使用。
浮动角度=105f;
浮动洋红色角=75f;
浮动黄度角=90f;
浮动键线角=15f;
newImage=新位图(宽度、高度);
newImage.SetResolution(image.HorizontalResolution,image.VerticalResolution);
使用(Graphics=Graphics.FromImage(newImage))
{
//减少锯齿状边缘。
graphics.SmoothingMode=SmoothingMode.AntiAlias;
graphics.InterpolationMode=InterpolationMode.HighQualityBicubic;
graphics.PixelOffsetMode=PixelOffsetMode.HighQuality;
graphics.CompositingQuality=CompositingQuality.HighQuality;
图形。清晰(颜色。白色);
使用(快速位图源位图=新的快速位图(图像))
{
对于(int y=0;y
输入图像
电流输出
正如您所看到的,由于绘制的椭圆没有角度,因此颜色输出不正确
所以这里有一个有效的解决方案。它不漂亮,速度不快(在我的笔记本电脑上2秒),但输出很好。它与Photoshop的输出不完全匹配,尽管我认为他们正在执行一些额外的工作 轻微的云纹图案有时会出现在不同的测试图像上,但对于当前的问题来说,去除云纹已超出范围 代码执行以下步骤
公共图像处理图像(图像工厂)
{
位图青色=空;
位图洋红色=空;
位图黄色=空;
位图键线=空;
位图newImage=null;
Image=factory.Image;
尝试
{
int-width=image.width;
int height=image.height;
//角度取自维基百科页面。
浮动角度=15f;
浮动洋红色角=75f;
浮动黄度角=0f;
浮动键线角=45f;
内径=4;
浮点乘法器=4*(浮点)数学Sqrt(2);
//青色从维基百科页面取样。
Brush cyanBrush=新的SolidBrush(颜色为argb(0,153,239));
画笔洋红色画笔=画笔。洋红色;
画笔黄色画笔=画笔。黄色;
刷键线刷;
//创造我们的形象。
青色=新位图(宽度、高度);
洋红色=新位图(宽度、高度);
黄色=新位图(宽度、高度);
keyline=新位图(宽度、高度);
newImage=新位图(宽度、高度);
//确保设置了正确的分辨率。
青色设置分辨率(图像.水平分辨率,图像.垂直分辨率);
洋红.设置分辨率(图像.水平分辨率,图像.垂直分辨率);
黄色。设置分辨率(图像。水平分辨率,图像。垂直分辨率);
public Image ProcessImage(ImageFactory factory)
{
Bitmap cyan = null;
Bitmap magenta = null;
Bitmap yellow = null;
Bitmap keyline = null;
Bitmap newImage = null;
Image image = factory.Image;
try
{
int width = image.Width;
int height = image.Height;
// Angles taken from Wikipedia page.
float cyanAngle = 15f;
float magentaAngle = 75f;
float yellowAngle = 0f;
float keylineAngle = 45f;
int diameter = 4;
float multiplier = 4 * (float)Math.Sqrt(2);
// Cyan color sampled from Wikipedia page.
Brush cyanBrush = new SolidBrush(Color.FromArgb(0, 153, 239));
Brush magentaBrush = Brushes.Magenta;
Brush yellowBrush = Brushes.Yellow;
Brush keylineBrush;
// Create our images.
cyan = new Bitmap(width, height);
magenta = new Bitmap(width, height);
yellow = new Bitmap(width, height);
keyline = new Bitmap(width, height);
newImage = new Bitmap(width, height);
// Ensure the correct resolution is set.
cyan.SetResolution(image.HorizontalResolution, image.VerticalResolution);
magenta.SetResolution(image.HorizontalResolution, image.VerticalResolution);
yellow.SetResolution(image.HorizontalResolution, image.VerticalResolution);
keyline.SetResolution(image.HorizontalResolution, image.VerticalResolution);
newImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);
// Check bounds against this.
Rectangle rectangle = new Rectangle(0, 0, width, height);
using (Graphics graphicsCyan = Graphics.FromImage(cyan))
using (Graphics graphicsMagenta = Graphics.FromImage(magenta))
using (Graphics graphicsYellow = Graphics.FromImage(yellow))
using (Graphics graphicsKeyline = Graphics.FromImage(keyline))
{
// Ensure cleared out.
graphicsCyan.Clear(Color.Transparent);
graphicsMagenta.Clear(Color.Transparent);
graphicsYellow.Clear(Color.Transparent);
graphicsKeyline.Clear(Color.Transparent);
// This is too slow. The graphics object can't be called within a parallel
// loop so we have to do it old school. :(
using (FastBitmap sourceBitmap = new FastBitmap(image))
{
for (int y = -height * 2; y < height * 2; y += diameter)
{
for (int x = -width * 2; x < width * 2; x += diameter)
{
Color color;
CmykColor cmykColor;
float brushWidth;
// Cyan
Point rotatedPoint = RotatePoint(new Point(x, y), new Point(0, 0), cyanAngle);
int angledX = rotatedPoint.X;
int angledY = rotatedPoint.Y;
if (rectangle.Contains(new Point(angledX, angledY)))
{
color = sourceBitmap.GetPixel(angledX, angledY);
cmykColor = color;
brushWidth = diameter * (cmykColor.C / 255f) * multiplier;
graphicsCyan.FillEllipse(cyanBrush, angledX, angledY, brushWidth, brushWidth);
}
// Magenta
rotatedPoint = RotatePoint(new Point(x, y), new Point(0, 0), magentaAngle);
angledX = rotatedPoint.X;
angledY = rotatedPoint.Y;
if (rectangle.Contains(new Point(angledX, angledY)))
{
color = sourceBitmap.GetPixel(angledX, angledY);
cmykColor = color;
brushWidth = diameter * (cmykColor.M / 255f) * multiplier;
graphicsMagenta.FillEllipse(magentaBrush, angledX, angledY, brushWidth, brushWidth);
}
// Yellow
rotatedPoint = RotatePoint(new Point(x, y), new Point(0, 0), yellowAngle);
angledX = rotatedPoint.X;
angledY = rotatedPoint.Y;
if (rectangle.Contains(new Point(angledX, angledY)))
{
color = sourceBitmap.GetPixel(angledX, angledY);
cmykColor = color;
brushWidth = diameter * (cmykColor.Y / 255f) * multiplier;
graphicsYellow.FillEllipse(yellowBrush, angledX, angledY, brushWidth, brushWidth);
}
// Keyline
rotatedPoint = RotatePoint(new Point(x, y), new Point(0, 0), keylineAngle);
angledX = rotatedPoint.X;
angledY = rotatedPoint.Y;
if (rectangle.Contains(new Point(angledX, angledY)))
{
color = sourceBitmap.GetPixel(angledX, angledY);
cmykColor = color;
brushWidth = diameter * (cmykColor.K / 255f) * multiplier;
// Just using blck is too dark.
keylineBrush = new SolidBrush(CmykColor.FromCmykColor(0, 0, 0, cmykColor.K));
graphicsKeyline.FillEllipse(keylineBrush, angledX, angledY, brushWidth, brushWidth);
}
}
}
}
// Set our white background.
using (Graphics graphics = Graphics.FromImage(newImage))
{
graphics.Clear(Color.White);
}
// Blend the colors now to mimic adaptive blending.
using (FastBitmap cyanBitmap = new FastBitmap(cyan))
using (FastBitmap magentaBitmap = new FastBitmap(magenta))
using (FastBitmap yellowBitmap = new FastBitmap(yellow))
using (FastBitmap keylineBitmap = new FastBitmap(keyline))
using (FastBitmap destinationBitmap = new FastBitmap(newImage))
{
Parallel.For(
0,
height,
y =>
{
for (int x = 0; x < width; x++)
{
// ReSharper disable AccessToDisposedClosure
Color cyanPixel = cyanBitmap.GetPixel(x, y);
Color magentaPixel = magentaBitmap.GetPixel(x, y);
Color yellowPixel = yellowBitmap.GetPixel(x, y);
Color keylinePixel = keylineBitmap.GetPixel(x, y);
CmykColor blended = cyanPixel.AddAsCmykColor(magentaPixel, yellowPixel, keylinePixel);
destinationBitmap.SetPixel(x, y, blended);
// ReSharper restore AccessToDisposedClosure
}
});
}
}
cyan.Dispose();
magenta.Dispose();
yellow.Dispose();
keyline.Dispose();
image.Dispose();
image = newImage;
}
catch (Exception ex)
{
if (cyan != null)
{
cyan.Dispose();
}
if (magenta != null)
{
magenta.Dispose();
}
if (yellow != null)
{
yellow.Dispose();
}
if (keyline != null)
{
keyline.Dispose();
}
if (newImage != null)
{
newImage.Dispose();
}
throw new ImageProcessingException("Error processing image with " + this.GetType().Name, ex);
}
return image;
}