Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cleaned DrawingTextAlongAPath and added f# scripts #21

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -219,4 +219,7 @@ artifacts/
**/output/*.jpg
**/output/*.jpeg
**/output/*.bmp
**/output/*.gif
**/output/*.gif
ImageSharp/AvatarWithRoundedCorner/fb.png
ImageSharp/AvatarWithRoundedCorner/fb-rounder.png
ImageSharp/AvatarWithRoundedCorner/fb-round.png
57 changes: 57 additions & 0 deletions ImageSharp/AvatarWithRoundedCorner/Program.fsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#r "nuget: SixLabors.ImageSharp"
#r "nuget: SixLabors.ImageSharp.Drawing, 1.0.0-beta15"

open SixLabors.ImageSharp
open SixLabors.ImageSharp.PixelFormats
open SixLabors.ImageSharp.Processing
open SixLabors.ImageSharp.Drawing
open SixLabors.ImageSharp.Drawing.Processing

let BuildCorners(imageWidth:float32, imageHeight:float32, cornerRadius:float32) =
// First create a square
let rect = new RectangularPolygon(-0.5f, -0.5f, cornerRadius, cornerRadius)

// Then cut out of the square a circle so we are left with a corner
let cornerTopLeft = rect.Clip(new EllipsePolygon(cornerRadius - 0.5f, cornerRadius - 0.5f, cornerRadius))

// Corner is now a corner shape positions top left
// let's make 3 more positioned correctly, we can do that by translating the original around the center of the image.
let rightPos = imageWidth - cornerTopLeft.Bounds.Width + 1f
let bottomPos = imageHeight - cornerTopLeft.Bounds.Height + 1f

// Move it across the width of the image - the width of the shape
let cornerTopRight = cornerTopLeft.RotateDegree(90f).Translate(rightPos, 0f)
let cornerBottomLeft = cornerTopLeft.RotateDegree(-90f).Translate(0f, bottomPos)
let cornerBottomRight = cornerTopLeft.RotateDegree(180f).Translate(rightPos, bottomPos)

new PathCollection(cornerTopLeft, cornerBottomLeft, cornerTopRight, cornerBottomRight)

// This method can be seen as an inline implementation of an `IImageProcessor`:
// (The combination of `IImageOperations.Apply()` + this could be replaced with an `IImageProcessor`)
let ApplyRoundedCorners(context:IImageProcessingContext, cornerRadius: float32):IImageProcessingContext =
let size = context.GetCurrentSize()
let corners = BuildCorners(float32 size.Width, float32 size.Height, cornerRadius)

context.SetGraphicsOptions(new GraphicsOptions(
Antialias = true,
// Enforces that any part of this shape that has color is punched out of the background
AlphaCompositionMode = PixelAlphaCompositionMode.DestOut
)) |> ignore

// Mutating in here as we already have a cloned original
// use any color (not Transparent), so the corners will be clipped
for path in corners do
context.Fill(Color.Red, path)|>ignore
context

// Implements a full image mutating pipeline operating on IImageProcessingContext
let ConvertToAvatar(context:IImageProcessingContext, size:Size, cornerRadius:float32):IImageProcessingContext =
ApplyRoundedCorners(context.Resize(ResizeOptions(
Size = size,
Mode = ResizeMode.Crop
)),cornerRadius)

let img = Image.Load("fb.jpg")
img.Clone(fun x -> ConvertToAvatar(x,new Size(200, 200), 20f) |> ignore).Save("fb.png")
img.Clone(fun x -> ConvertToAvatar(x,new Size(200, 200), 100f) |> ignore).Save("fb-round.png")
img.Clone(fun x -> ConvertToAvatar(x,new Size(200, 200), 150f) |> ignore).Save("fb-rounder.png")
4 changes: 2 additions & 2 deletions ImageSharp/DrawingTextAlongAPath/Program.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.

using SixLabors.Fonts;
Expand Down Expand Up @@ -50,4 +50,4 @@ static void Main(string[] args)
img.Save("output/wordart.png");
}
}
}
}
40 changes: 40 additions & 0 deletions ImageSharp/DrawingTextAlongAPath/Program.fsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#r "nuget: SixLabors.ImageSharp"
#r "nuget: SixLabors.ImageSharp.Drawing, 1.0.0-beta15"

open System
open SixLabors.Fonts
open SixLabors.ImageSharp
open SixLabors.ImageSharp.PixelFormats
open SixLabors.ImageSharp.Processing
open SixLabors.ImageSharp.Drawing
open SixLabors.ImageSharp.Drawing.Processing

let img = new Image<Rgba32>(1500, 500)
let pathBuilder = new PathBuilder()
pathBuilder.SetOrigin(new PointF(500f, 0f))
pathBuilder.AddCubicBezier(new PointF(50f, 450f), new PointF(200f, 50f), new PointF(300f, 50f), new PointF(450f, 450f))

// Add more complex paths and shapes here.
let path = pathBuilder.Build()

// For production application we would recomend you create a FontCollection
// singleton and manually install the ttf fonts yourself as using SystemFonts
// can be expensive and you risk font existing or not existing on a deployment
// by deployment basis.
let font = SystemFonts.CreateFont("Microsoft Sans Serif", 39f, FontStyle.Regular)
let text = "Hello World Hello World Hello World Hello World Hello World"

// Draw the text along the path wrapping at the end of the line
let textOptions = new TextOptions(font)
textOptions.WrappingLength <- path.ComputeLength()
textOptions.VerticalAlignment <- VerticalAlignment.Bottom
textOptions.HorizontalAlignment <- HorizontalAlignment.Left

// Let's generate the text as a set of vectors drawn along the path
let glyphs = TextBuilder.GenerateGlyphs(text, path, textOptions)

img.Mutate(fun ctx -> ctx.Fill(Color.White) // white background image
.Draw(Color.Gray, 3f, path) // draw the path so we can see what the text is supposed to be following
.Fill(Color.Black, glyphs)|>ignore)

img.Save("wordart.png")