看看这个.
我认为你需要的一切.
编辑
public static bool Invert(Bitmap b)
{
BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
int stride = bmData.Stride;
System.IntPtr Scan0 = bmData.Scan0;
// Create the Byte-Array
int bytes = Math.Abs(bmData.Stride) * b.Height;
byte[] p = new byte[bytes];
// Copy RGB values into Byte-Array
System.Runtime.InteropServices.Marshal.Copy(Scan0, p, 0, bytes);
int nOffset = stride - b.Width * 3;
int nWidth = b.Width * 3;
int i = 0;
for (int y = 0; y < b.Height; ++y)
{
for (int x = 0; x < nWidth; ++x)
{
p[i] = (byte)(255 - p[i]);
++i;
}
i += nOffset;
}
// Copy RGB back to image
System.Runtime.InteropServices.Marshal.Copy(p, 0, Scan0, bytes);
b.UnlockBits(bmData);
return true;
}
Run Code Online (Sandbox Code Playgroud)
编辑
你去:
public class Lomography
{
public static Bitmap getImage(Bitmap bmp)
{
using (Graphics g = Graphics.FromImage(bmp))
{
using (Bitmap CurveLayer = (Bitmap)bmp.Clone())
{
Lomography.SCurve(CurveLayer);
g.DrawImage(CurveLayer, new Rectangle(0, 0, bmp.Width, bmp.Height));
}
}
using (Graphics g = Graphics.FromImage(bmp))
{
using (Bitmap ColorLayer = (Bitmap)bmp.Clone())
{
Lomography.Colorize(ColorLayer, -12, 25, -12, Lomography.ColorArea.Shadows);
g.DrawImage(ColorLayer, new Rectangle(0, 0, bmp.Width, bmp.Height), 0, 0, bmp.Width, bmp.Height, GraphicsUnit.Pixel);
}
}
using (Graphics g = Graphics.FromImage(bmp))
{
using (Bitmap ColorLayer = (Bitmap)bmp.Clone())
{
Lomography.Colorize(ColorLayer, 12, 12, -25, Lomography.ColorArea.Hightlights);
g.DrawImage(ColorLayer, new Rectangle(0, 0, bmp.Width, bmp.Height), 0, 0, bmp.Width, bmp.Height, GraphicsUnit.Pixel);
}
}
using (Graphics g = Graphics.FromImage(bmp))
{
RectangleF gradient = new RectangleF(-bmp.Width * 0.3f, -bmp.Height * 0.3f, bmp.Width * 1.6f, bmp.Height * 1.6f);
GraphicsPath gp = new GraphicsPath();
gp.AddEllipse(gradient);
using (PathGradientBrush pgb = new PathGradientBrush(gp))
{
pgb.CenterColor = Color.Yellow;
pgb.CenterPoint = new Point(bmp.Width / 2, bmp.Height / 2);
ColorBlend cb = new ColorBlend(3);
cb.Colors[0] = Color.Black;
cb.Colors[1] = Color.Transparent;
cb.Colors[2] = Color.Transparent;
cb.Positions[0] = 0f;
cb.Positions[1] = 0.55f;
cb.Positions[2] = 1f;
pgb.InterpolationColors = cb;
g.FillEllipse(pgb, gradient);
}
}
return bmp;
}
public enum ColorArea
{
Midtones,
Shadows,
Hightlights
}
public static bool Colorize(Bitmap b, int red, int green, int blue, ColorArea ca)
{
if (red < -255 || red > 255) return false;
if (green < -255 || green > 255) return false;
if (blue < -255 || blue > 255) return false;
BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
int bytes = Math.Abs(bmData.Stride) * b.Height;
int stride = bmData.Stride;
System.IntPtr Scan0 = bmData.Scan0;
byte[] p = new byte[bytes];
System.Runtime.InteropServices.Marshal.Copy(Scan0, p, 0, bytes);
int i = 0;
int nOffset = stride - b.Width * 3;
int nPixel;
for (int y = 0; y < b.Height; ++y)
{
for (int x = 0; x < b.Width; ++x)
{
int pdif = (p[i + 2] + p[i + 1] + p[i]) / 3;
int newred = p[i + 2];
int newgreen = p[i + 1];
int newblue = p[i];
if (ca == ColorArea.Shadows)
{
float multi = (1 - newred / 255);
newred += (int)(red * multi);
multi = (1 - newgreen / 255);
newgreen += (int)(green * multi);
multi = (1 - newblue / 255);
newblue += (int)(blue * multi);
}
if (ca == ColorArea.Hightlights)
{
float multi = (newred / 255);
newred += (int)(red * multi);
multi = (newgreen / 255);
newgreen += (int)(green * multi);
multi = (newblue / 255);
newblue += (int)(blue * multi);
}
if (ca == ColorArea.Midtones)
{
float multi = 0;
if (newred > 127)
multi = 127f / newred;
else
multi = newred / 127f;
newred += (int)(red * multi);
if (newgreen > 127)
multi = 127f / newgreen;
else
multi = newgreen / 127f;
newgreen += (int)(green * multi);
if (newblue > 127)
multi = 127f / newblue;
else
multi = newblue / 127f;
newblue += (int)(blue * multi);
}
nPixel = newred;
nPixel = Math.Max(nPixel, 0);
p[i + 2] = (byte)Math.Min(255, nPixel);
nPixel = newgreen;
nPixel = Math.Max(nPixel, 0);
p[i + 1] = (byte)Math.Min(255, nPixel);
nPixel = newblue;
nPixel = Math.Max(nPixel, 0);
p[i + 0] = (byte)Math.Min(255, nPixel);
i += 3;
}
i += nOffset;
}
System.Runtime.InteropServices.Marshal.Copy(p, 0, Scan0, bytes);
b.UnlockBits(bmData);
return true;
}
public static bool SCurve(Bitmap b)
{
BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
int bytes = Math.Abs(bmData.Stride) * b.Height;
int stride = bmData.Stride;
System.IntPtr Scan0 = bmData.Scan0;
byte[] p = new byte[bytes];
System.Runtime.InteropServices.Marshal.Copy(Scan0, p, 0, bytes);
int i = 0;
int nOffset = stride - b.Width * 3;
int nPixel;
Point[] points = GetCoordinates();
for (int y = 0; y < b.Height; ++y)
{
for (int x = 0; x < b.Width; ++x)
{
int hue = (p[i] == 255) ? 255 : -1;
int hue1 = (p[i + 1] == 255) ? 255 : -1;
int hue2 = (p[i + 2] == 255) ? 255 : -1;
int p2 = p[i + 2];
foreach (var point in points)
{
if (hue2 == -1 && point.X >= p[i + 2])
hue2 = point.Y;
if (hue1 == -1 && point.X >= p[i + 1])
hue1 = point.Y;
if (hue == -1 && point.X >= p[i])
hue = point.Y;
if (hue != -1 && hue1 != -1 && hue2 != -1)
break;
}
nPixel = hue2;
nPixel = Math.Max(nPixel, 0);
p[i + 2] = (byte)Math.Min(255, nPixel);
nPixel = hue1;
nPixel = Math.Max(nPixel, 0);
p[i + 1] = (byte)Math.Min(255, nPixel);
nPixel = hue;
nPixel = Math.Max(nPixel, 0);
p[i + 0] = (byte)Math.Min(255, nPixel);
i += 3;
}
i += nOffset;
}
System.Runtime.InteropServices.Marshal.Copy(p, 0, Scan0, bytes);
b.UnlockBits(bmData);
return true;
}
private static Point[] GetCoordinates()
{
List<Point> points = new List<Point>();
int height = 255;
int width = 255;
double y0 = height;
double y1 = height;
double y2 = height * 0.75d;
double y3 = height * 0.5d;
double x0 = 0;
double x1 = width * 0.25d;
double x2 = width * 0.35d;
double x3 = width * 0.5d;
for (int i = 0; i < 1000; i++)
{
double t = i / 1000d;
double xt = (-x0 + 3 * x1 - 3 * x2 + x3) * (t * t * t) + 3 * (x0 - 2 * x1 + x2) * (t * t) + 3 * (-x0 + x1) * t + x0;
double yt = (-y0 + 3 * y1 - 3 * y2 + y3) * (t * t * t) + 3 * (y0 - 2 * y1 + y2) * (t * t) + 3 * (-y0 + y1) * t + y0;
points.Add(new Point((int)xt, 255 - (int)yt));
}
y0 = height * 0.5d;
y1 = height * 0.25d;
y2 = 0;
y3 = 0;
x0 = width * 0.5d;
x1 = width * 0.65d;
x2 = width * 0.75d;
x3 = width;
for (int i = 0; i < 1000; i++)
{
double t = i / 1000d;
double xt = (-x0 + 3 * x1 - 3 * x2 + x3) * (t * t * t) + 3 * (x0 - 2 * x1 + x2) * (t * t) + 3 * (-x0 + x1) * t + x0;
double yt = (-y0 + 3 * y1 - 3 * y2 + y3) * (t * t * t) + 3 * (y0 - 2 * y1 + y2) * (t * t) + 3 * (-y0 + y1) * t + y0;
points.Add(new Point((int)xt, 255 - (int)yt));
}
return points.ToArray();
}
}
Run Code Online (Sandbox Code Playgroud)
使用颜色和曲线稍微玩一下,以获得最佳效果.
曲线中的点是使用GetCoordinates中的2个三次贝塞尔曲线计算的.第一次运行获得左下曲线的点数.第二轮比赛获得了正确的分数.

编辑
您还可以使用此示例项目来获得最佳颜色和曲线.(你可以拖动曲线的点)

编辑 为了加快曲线更改后加速CurveCoordinates,而不是SCurve函数.将曲线坐标保存在int数组中(int [256]).现在你不必循环和搜索点,只需从数组中获取它:hue = y = points [x]
public bool SCurve(Bitmap b)
{
BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
int bytes = Math.Abs(bmData.Stride) * b.Height;
int stride = bmData.Stride;
System.IntPtr Scan0 = bmData.Scan0;
byte[] p = new byte[bytes];
System.Runtime.InteropServices.Marshal.Copy(Scan0, p, 0, bytes);
int i = 0;
int nOffset = stride - b.Width * 3;
int nPixel;
int[] points = GetCoordinates();
if (points == null)
return false;
for (int y = 0; y < b.Height; ++y)
{
for (int x = 0; x < b.Width; ++x)
{
if (state == State.Abort)
{
b.UnlockBits(bmData);
return false;
}
int hue = points[p[i]];
int hue1 = points[p[i + 1]];
int hue2 = points[p[i + 2]];
int p2 = p[i + 2];
nPixel = hue2;
nPixel = Math.Max(nPixel, 0);
p[i + 2] = (byte)Math.Min(255, nPixel);
nPixel = hue1;
nPixel = Math.Max(nPixel, 0);
p[i + 1] = (byte)Math.Min(255, nPixel);
nPixel = hue;
nPixel = Math.Max(nPixel, 0);
p[i + 0] = (byte)Math.Min(255, nPixel);
i += 3;
}
i += nOffset;
}
System.Runtime.InteropServices.Marshal.Copy(p, 0, Scan0, bytes);
b.UnlockBits(bmData);
return true;
}
private int[] GetCoordinates()
{
int[] points = new int[256];
int height = 255;
int width = 255;
double y0 = height;
double y1 = height * (curve1.p1.Y / (double)curve1.Height);
double y2 = height * (curve1.p1.Y / (double)curve1.Height);
double y3 = height * 0.5d;
double x0 = 0;
double x1 = width * (curve1.p1.X / (double)curve1.Width);
double x2 = width * (curve1.p2.X / (double)curve1.Width);
double x3 = width * 0.5d;
for (int i = 0; i < 1000; i++)
{
double t = i / 1000d;
double xt = (-x0 + 3 * x1 - 3 * x2 + x3) * (t * t * t) + 3 * (x0 - 2 * x1 + x2) * (t * t) + 3 * (-x0 + x1) * t + x0;
double yt = (-y0 + 3 * y1 - 3 * y2 + y3) * (t * t * t) + 3 * (y0 - 2 * y1 + y2) * (t * t) + 3 * (-y0 + y1) * t + y0;
points[(int)xt] = 255 - (int)yt;
}
y0 = height * 0.5d;
y1 = height * (curve1.p3.Y / (double)curve1.Height); ;
y2 = height * (curve1.p4.Y / curve1.Height);
y3 = 0;
x0 = width * 0.5d;
x1 = width * (curve1.p3.X / (double)curve1.Width);
x2 = width * (curve1.p4.X / (double)curve1.Width);
x3 = width;
for (int i = 0; i < 1000; i++)
{
double t = i / 1000d;
double xt = (-x0 + 3 * x1 - 3 * x2 + x3) * (t * t * t) + 3 * (x0 - 2 * x1 + x2) * (t * t) + 3 * (-x0 + x1) * t + x0;
double yt = (-y0 + 3 * y1 - 3 * y2 + y3) * (t * t * t) + 3 * (y0 - 2 * y1 + y2) * (t * t) + 3 * (-y0 + y1) * t + y0;
points[(int)xt] = 255 - (int)yt;
}
points[255] = (int)(255 - y3);
return points;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1374 次 |
| 最近记录: |