Skip to content

Instantly share code, notes, and snippets.

@aspose-com-gists
Last active October 2, 2023 11:26
C# .NET showcases for Aspose.Drawing 2D drawing engine with System.Drawing compatible API
Bitmap bitmap2 = new(w, h);
Graphics g2 = Graphics.FromImage(bitmap2);
g2.SmoothingMode = SmoothingMode.HighQuality;
g2.TextRenderingHint = TextRenderingHint.AntiAlias;
g2.Clip = new Region(carBody);
foreach (DesignElement de in skin.Design)
{
if (de.Banner is not null)
{
Brush brush2 = new SolidBrush(de.Banner.Color);
g2.DrawString(de.Banner.Text, de.Banner.Font, brush2, de.Banner.Place.X, de.Banner.Place.Y);
}
if (de.Logo is not null)
{
Bitmap logo = new(de.Logo.ImageFile);
g2.DrawImage(logo, new RectangleF(de.Logo.Place.X, de.Logo.Place.Y, logo.Width, logo.Height));
}
}
g.Clip = new Region(carBody);
ImageAttributes imageAttributes = new();
ColorMatrix colorMatrix = new(new float[][]
{
new float[] { 1, 0, 0, 0, 0 },
new float[] { 0, 1, 0, 0, 0 },
new float[] { 0, 0, 1, 0, 0 },
new float[] { 0, 0, 0, 0.7f, 0 },
new float[] { 0, 0, 0, 0, 1 }
});
imageAttributes.SetColorMatrix(
colorMatrix,
ColorMatrixFlag.Default,
ColorAdjustType.Bitmap);
PointF[] destParallelogram = new PointF[]
{
new PointF( 0, 0 ),
new PointF( w, 0 ),
new PointF( 0, h ),
};
g.DrawImage(
bitmap2,
destParallelogram,
new RectangleF(0, 0, w, h),
GraphicsUnit.Pixel,
imageAttributes);
private static readonly Brush edgeBrush = Brushes.Magenta;
private static void DrawEdge(int w, int h, GraphicsPath carBody, Bitmap frame, float percent)
{
float edgeSize = 5.0f;
float edgePosition = w * percent / 100;
Rectangle rect = new(
(int)(edgePosition - edgeSize / 2), 0,
(int)(edgeSize), h);
Region edge = new(carBody);
edge.Intersect(rect);
Graphics g = Graphics.FromImage(frame);
g.FillRegion(edgeBrush, edge);
}
private static Bitmap DrawFrame(int w, int h, GraphicsPath carBody, Skin skin)
{
Bitmap bitmap = new(w, h);
Graphics g = Graphics.FromImage(bitmap);
g.Clear(Color.White);
g.SmoothingMode = SmoothingMode.HighQuality;
g.TextRenderingHint = TextRenderingHint.AntiAlias;
Bitmap rasterCar = new(Path.Combine(inputDirectory, "carbody-sedan-04.png"));
g.DrawImage(rasterCar, new RectangleF(0, 0, w, h));
Brush brush1 = new SolidBrush(skin.Background);
g.FillPath(brush1, carBody);
//...
}
Bitmap frame = new(1920, 1080, PixelFormat.Format32bppPArgb);
Graphics g = Graphics.FromImage(frame);
g.SmoothingMode = SmoothingMode.HighQuality;
for (int f1 = 0; f1 < frames.Count; f1++)
{
int f2 = (f1 + 1) % frames.Count;
frame1 = frames[f1];
frame2 = frames[f2];
for (int i = 0; i < (makeVideo ? 200 : 1); i++)
{
++frameNumber;
percent = makeVideo ? i * step % 100 : 25;
mixedFrame = Mix(w, h, frame1, frame2, percent);
DrawEdge(w, h, carBody, mixedFrame, percent);
for (int n = 0; n < 2; n++)
{
for (int m = 0; m < 3; m++)
{
g.DrawImage(mixedFrame, (1920 - 50) / 2 * n, (1080 - 50) / 3 * m - 40);
}
}
string fileName = string.Format("{0}/{1:d5}.png", outputDirectory, frameNumber);
frame.Save(fileName);
Console.WriteLine(fileName);
}
}
GraphicsPath carBody = MakeCarBody(h);
foreach (Skin skin in skins)
{
frames.Add(DrawFrame(w, h, carBody, skin));
}
private static Bitmap Mix(int w, int h, Bitmap frame1, Bitmap frame2, float percent)
{
Bitmap bitmap = new(w, h);
Graphics g = Graphics.FromImage(bitmap);
g.SmoothingMode = SmoothingMode.HighQuality;
float edgePosition = w * percent / 100;
RectangleF rect1 = new(edgePosition, 0, w - edgePosition, h);
g.DrawImage(frame1, rect1, rect1, GraphicsUnit.Pixel);
RectangleF rect2 = new(0, 0, edgePosition, h);
g.DrawImage(frame2, rect2, rect2, GraphicsUnit.Pixel);
return bitmap;
}
Skin skin1 = new() { Background = Color.FromArgb(120, 0, 80, 80) };
skins.Add(skin1);
Skin skin2 = new() { Background = Color.FromArgb(80, 180, 80, 0) };
skins.Add(skin2);
Skin skin3 = new() { Background = Color.FromArgb(80, 80, 80, 180) };
skin3.Design.Add(new DesignElement(
new Logo(Path.Combine(inputDirectory, "brit-01.png"), new PointF(333, h - 253))));
skin3.Design.Add(new DesignElement(
new Banner("KEWIN", new Font("Arial", 140, FontStyle.Bold, GraphicsUnit.Pixel),
Color.FromArgb(120, 0, 255, 255), new PointF(350, h - 277))));
skins.Add(skin3);
Skin skin4 = new() { Background = Color.FromArgb(120, 255, 255, 0) };
skin4.Design.Add(new DesignElement(
new Logo(Path.Combine(inputDirectory, "anchor-01.png"), new PointF(275, h - 290))));
skin4.Design.Add(new DesignElement(
new Banner("ANCHOR", new Font("Verdana", 120, FontStyle.Bold | FontStyle.Italic, GraphicsUnit.Pixel),
Color.FromArgb(120, 255, 0, 0), new PointF(250, h - 285))));
skins.Add(skin4);
ImageAttributes imageAttributes = new();
ColorMatrix colorMatrix = new(
new float[][]
{
new float[] { 1, 0, 0, 0, 0 },
new float[] { 0, 1, 0, 0, 0 },
new float[] { 0, 0, 1, 0, 0 },
new float[] { 0, 0, 0, 0.55f, 0 },
new float[] { 0, 0, 0, 0, 1 }
}
);
imageAttributes.SetColorMatrix(
colorMatrix,
ColorMatrixFlag.Default,
ColorAdjustType.Bitmap);
float x = 1920 / 2 - w / 2;
float y = 1080 / 2 - h / 2;
PointF[] destParallelogram = new PointF[]
{
new PointF( x, y ),
new PointF( x + w, y ),
new PointF( x, y + h ),
};
RectangleF rect = new(0, 0, w, h);
private static Bitmap Mix(Bitmap bitmap, PointF[] destParallelogram,
RectangleF rect, ImageAttributes imageAttributes)
{
CalcFrameNumbers();
Bitmap frame = BackgroundMix();
Graphics g2 = Graphics.FromImage(frame);
g2.CompositingQuality = CompositingQuality.HighQuality;
g2.DrawImage(
bitmap,
destParallelogram,
rect,
GraphicsUnit.Pixel,
imageAttributes);
return frame;
}
private static readonly int k = 60; // Frame number for transition from one key position
// to another on the creeping line.
for (int i = 0; i < frameLimit; i++)
{
if (i % k == 0)
{
ShiftRibbonStrings(ribbons);
}
++frameNumber;
g.Clear(bgColor);
DrawRibbons(ribbons, g);
RedrawRibbons(ribbons, segments1, segments2, g);
Bitmap frame = Mix(bitmap, destParallelogram, rect, imageAttributes);
string fileName = Path.Combine(outputDirectory, $"{frameNumber:d5}.png");
frame.Save(fileName);
Console.WriteLine(fileName);
}
GraphicsPath flatPath1 = (GraphicsPath)path1.Clone();
GraphicsPath flatPath2 = (GraphicsPath)path2.Clone();
flatPath1.Flatten();
flatPath2.Flatten();
List<Node> nodes = new();
List<Span> segments = new();
List<Span> segments1 = new();
List<Span> segments2 = new();
PointF[] points1 = flatPath1.PathPoints;
PointF[] points2 = flatPath2.PathPoints;
AddSpans(segments1, points1);
AddSpans(segments2, points2);
segments.AddRange(segments2);
segments.AddRange(segments1);
private static readonly float ribbonInnerWidth = 48;
private static readonly float ribbonStroke = 4;
private static readonly Pen penInner = new(Color.FromArgb(255, 60, 60, 90), ribbonInnerWidth);
private static readonly Pen penBorder = new(Color.White, ribbonInnerWidth + ribbonStroke * 2);
private static void DrawRibbon(Ribbon ribbon, Graphics g)
{
g.DrawPath(penBorder, ribbon.Path);
g.DrawPath(penInner, ribbon.Path);
GraphicsPath inner = (GraphicsPath)ribbon.Path.Clone();
inner.Widen(penBorder);
DrawTextOnPath(g, ribbon.Text, ribbon);
if (ribbon.Node1 is null || ribbon.Node3 is null)
{
return;
}
PathGradientBrush brush1 = MakeBrush(ribbon.Node1.Point);
g.FillPath(brush1, inner);
PathGradientBrush brush3 = MakeBrush(ribbon.Node3.Point);
g.FillPath(brush3, inner);
}
private static PathGradientBrush MakeBrush(PointF pt)
{
float r = 80;
GraphicsPath path = new();
path.AddEllipse(pt.X - r, pt.Y - r, r * 2, r * 2);
PathGradientBrush brush = new(path) { CenterColor = Color.FromArgb(255, 0, 0, 0) };
Color[] colors = { Color.FromArgb(0, 60, 60, 90) };
brush.SurroundColors = colors;
return brush;
}
private static void RedrawRibbons(
List<Ribbon> ribbons, List<Span> segments1, List<Span> segments2, Graphics g)
{
for (int i = 0; i < ribbons.Count; i++)
{
Ribbon ribbon = ribbons[i];
if (ribbon.Node2 is not null)
{
Node node = ribbon.Node2;
GraphicsPath part1 = ribbon.Path;
GraphicsPath part2 = MakeUnderPart(ribbon.Node2, segments1, segments2);
GraphicsPath widenPart1 = (GraphicsPath)part1.Clone();
GraphicsPath widenPart2 = (GraphicsPath)part2.Clone();
widenPart1.Widen(penWide);
widenPart2.Widen(penWide);
Region interParts = new(widenPart1);
interParts.Intersect(new Region(widenPart2));
g.Clip = interParts;
g.Clear(bgColor);
if (node.Ribbon1 is not null && node.Ribbon2 is not null && node.Ribbon3 is not null)
{
DrawRibbon(node.Ribbon1, g);
DrawRibbon(node.Ribbon3, g);
DrawRibbon(node.Ribbon2, g);
}
g.ResetClip();
}
}
}
private static void DrawTextOnPath(Graphics g, string txt, Ribbon ribbon)
{
for (int i = 1; i < ribbon.Shifts.Count - 1; i++)
{
string sub = txt.Substring(i, 1);
Shift shift1 = ribbon.Shifts[i];
Shift shift2 = ribbon.Shifts[i + 1];
int n = (frameNumber - 1) % k;
Shift shift = new(
shift1.X + (shift2.X - shift1.X) / k * n,
shift1.Y + (shift2.Y - shift1.Y) / k * n,
shift1.Angle + SmallestAngleDiff(shift1.Angle, shift2.Angle) / k * n,
shift1.Hint + (shift2.Hint - shift1.Hint) / k * n);
DrawTextOnSegment(g, sub, shift);
}
}
private static void DrawTextOnSegment(Graphics g, string txt, Shift shift)
{
GraphicsState state = g.Save();
g.TranslateTransform(0, shift.Hint, MatrixOrder.Append);
g.RotateTransform(shift.Angle, MatrixOrder.Append);
g.TranslateTransform(shift.X, shift.Y, MatrixOrder.Append);
GraphicsPath path = new();
path.AddString(txt, fontFamily, 0, emSize, new Point(0, 0), null);
g.FillPath(fontBrush, path);
g.Restore(state);
}
int num = 0;
for (int i = 0; i < segments.Count; i++)
{
for (int j = i + 1; j < segments.Count; j++)
{
Span segA = segments[i];
Span segB = segments[j];
if (segA[0].Equals(segB[0]) || segA[0].Equals(segB[1]) ||
segA[1].Equals(segB[0]) || segA[1].Equals(segB[1]))
{
continue;
}
FindIntersection(
segA[0], segA[1], segB[0], segB[1],
out bool segments_intersect, out PointF intersection_point);
if (segments_intersect)
{
Node node = new();
segA.Node = node;
segB.Node = node;
node.Point = intersection_point;
node.SegA = segA;
node.SegB = segB;
node.Otherwise = num % 2 == 0;
nodes.Add(node);
num++;
}
}
}
Node last = nodes[^1];
last.Otherwise = !last.Otherwise;
List<Ribbon> ribbons = new();
MakeRibbons(ribbons, segments2);
MakeRibbons(ribbons, segments1);
CalcShifts(ribbons, g);
internal class Node
{
public PointF Point;
public Span? SegA;
public Span? SegB;
public bool Otherwise;
public Ribbon? Ribbon1;
public Ribbon? Ribbon2;
public Ribbon? Ribbon3;
}
internal class Ribbon
{
public GraphicsPath Path = new();
public string Text = RandomString();
public List<Shift> Shifts = new();
public Node? Node1;
public Node? Node2;
public Node? Node3;
}
internal class Shift
{
public float X;
public float Y;
public float Angle;
public float Hint;
public Shift(float x, float y, float angle, float hint)
{
this.X = x;
this.Y = y;
this.Angle = angle;
this.Hint = hint;
}
}
private static readonly string text = "ᛦᛨᛩᛪ᛭ᛮᛯᛰᚠᛅᛆᛇᛈᛉᛊᛋᛏᛐᛒᛓᛗᛘᛚᛝᛞᛟᛠᛡᛢᛣᛥᚨᚩᚪᚫᚬᚭᚮᚯᚰᚱᚳᚴᚷᚸᚹᚺᚻᚼᚾᚿᛀ";
private static string ShiftString(string t)
{
string text2 = text.Remove(text.IndexOf(t[0]), 1);
int i = random.Next(0, text2.Length - 1);
return text2[i] + t[..^1];
}
private static string RandomString()
{
string text2 = text;
for (int i = 0; i < text2.Length; i++)
{
text2 = ShiftString(text2);
}
return text2;
}
Rectangle rectangle = new(0, fontSize, w, fontSize);
GraphicsPath path = new();
path.AddString(word, fontFamily, (int)FontStyle.Bold, fontSize, rectangle, stringFormat);
GraphicsPath path2 = new();
path2.AddString(word, fontFamily, (int)FontStyle.Bold, fontSize, rectangle, stringFormat);
VisitPoints(path, path2, graphics, AddEllipseToPath);
private static void VisitPoints(
GraphicsPath path,
GraphicsPath path2,
Graphics graphics,
Action<RectangleF, Graphics, GraphicsPath> handler)
{
PointF[] points = path.PathPoints;
PointF prev = new(0, 0);
float diameter = nutDiameter;
for (int i = 0; i < path.PointCount; ++i)
{
PointF point = points[i];
if (i % 5 == 0 && Distance(point, prev) > 12)
{
RectangleF rectangle = new(
point.X - diameter / 2,
point.Y - diameter / 2,
diameter,
diameter);
handler(rectangle, graphics, path2);
}
prev = point;
}
}
private static void AddEllipseToPath(RectangleF rectangle, Graphics graphics, GraphicsPath path)
{
path.AddEllipse(rectangle);
}
private static readonly string word = "Lollipop";
private static readonly Size frameSize = new(1920, 1080);
for (int i = 0; i < (makeVideo ? frames : 1); ++i)
{
nutDiameter = 35.0f - (i % 20);
Bitmap image1 = DrawWord(word);
Bitmap bitmap = DrawReflection(image1, frameSize.Width, frameSize.Height);
string fileName = string.Format("{0}/{1:d4}.png", outputDirectory, i + 1);
bitmap.Save(fileName);
Console.WriteLine(fileName);
}
public static Bitmap DrawReflection(Bitmap image1, int w, int h)
{
Bitmap bitmap = new(w, h, System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
Graphics graphics = Graphics.FromImage(bitmap);
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.Clear(Color.Black);
float bw = image1.Width;
float bh = image1.Height;
graphics.DrawImage(image1, new RectangleF(
w / 2 - bw / 2,
horizon - bh,
bw,
bh));
graphics.DrawImage(image1, new RectangleF(
w / 2 - bw / 2,
horizon + bh / 2,
bw,
-bh / 2));
RectangleF rectangle = new(
w / 2 - bw / 2,
horizon,
bw,
bh / 2);
LinearGradientBrush brush = new(
rectangle,
Color.FromArgb(150, 0, 0, 0),
Color.FromArgb(255, 0, 0, 0),
LinearGradientMode.Vertical);
graphics.FillRectangle(brush, rectangle);
return bitmap;
}
private static Bitmap DrawWord(string word)
{
int w = word.Length * fontSize;
int h = fontSize * 3;
int margin = 5;
Bitmap bitmap = new(w, h, System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
Graphics graphics = Graphics.FromImage(bitmap);
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.Clear(Color.Black);
FontFamily fontFamily = new("Arial");
StringFormat stringFormat = new()
{
Alignment = StringAlignment.Center,
LineAlignment = StringAlignment.Center
};
//...
}
Random r = new(seed);
int half = 15; // of pen amount
List<Color> colors = GetColors(half, r);
private static List<Color> GetColors(int half, Random r)
{
int start = 0;
int range = 255;
List<Color> colors = new();
int count = half * 2;
for (int i = 0; i < count; ++i)
{
Color c;
if (i < half)
{
c = Color.FromArgb(start + r.Next(range), start + r.Next(range), start + r.Next(range));
colors.Add(c);
}
else
{
Color o = colors[i % half];
c = Color.FromArgb(255 - o.R, 255 - o.G, 255 - o.B);
colors.Add(c);
}
}
List<Color> palette = new();
Bitmap image1 = new(Path.Combine(inputDirectory, "palette.png"));
int w = image1.Width;
int index = r.Next(w);
int step = w / count;
for (int i = 0; i < count; ++i)
{
index += step;
index %= w - 1;
Color c = image1.GetPixel(index, 0);
palette.Add(c);
}
List<Color> result = new();
int interval = 4;
for (int i = 0; i < count; ++i)
{
Color c;
if (i % interval == 0)
{
c = Blend(palette[i], colors[i], 0.7);
}
else if (i % interval == 1)
{
c = Blend(palette[i], colors[i], 0.4);
}
else if (i % interval == 2)
{
c = Blend(palette[i], colors[i], 0.2);
}
else
{
c = Blend(palette[i], colors[i], 0.1);
}
result.Add(c);
}
return result;
}
private static Color Blend(Color color, Color backColor, double amount)
{
byte r = (byte)(color.R * amount + backColor.R * (1 - amount));
byte g = (byte)(color.G * amount + backColor.G * (1 - amount));
byte b = (byte)(color.B * amount + backColor.B * (1 - amount));
return Color.FromArgb(r, g, b);
}
int doubleStroke = 3 * 2; // the double width of stroke is increment of real pen width
Pen widest = new(colors[0], half * 2 * doubleStroke);
for (int i = 0; i < half * 2; ++i)
{
Color c = colors[i];
Pen pen = new(c, (half * 2 - i) * doubleStroke)
{
LineJoin = LineJoin.Round
};
if (i == 0)
{
widest = pen;
}
graphics.DrawPath(pen, path2);
}
LinearGradientBrush brush = new(
rectangle,
Color.White,
Color.Gray,
LinearGradientMode.Vertical);
graphics.FillPath(brush, path);
VisitPoints(path, path, graphics, DrawAndFillEllipse);
path2.Widen(widest);
bitmap = Crop(bitmap, path2, margin);
return bitmap;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment