Browse Source

add SkiaSharp versions of the System.Drawing functionality.

None of the SkiaSharp code has tests in Test Centre.
master
Craig Oates 6 years ago
parent
commit
0e381f824c
  1. 8
      DeathSocket/ColourServices.fs
  2. 60
      DeathSocket/Domain.fs
  3. 151
      DeathSocket/GridPainter.fs
  4. 147
      DeathSocket/ImageServices.fs
  5. 8
      DeathSocket/Validation.fs
  6. 33
      DeathSocketCLI/Commands.fs
  7. 79
      DeathSocketCLI/Validation.fs

8
DeathSocket/ColourServices.fs

@ -15,10 +15,4 @@
let makeBrushFromRGBA r g b a = let makeBrushFromRGBA r g b a =
let colour = Color.FromArgb (a, r, g, b) let colour = Color.FromArgb (a, r, g, b)
new SolidBrush (colour) new SolidBrush (colour)
let makeSkiaColour r g b =
let red = BitConverter.GetBytes (int r)
let green = BitConverter.GetBytes (int g)
let blue = BitConverter.GetBytes (int b)
new SKColor (red.[0], green.[0], blue.[0])

60
DeathSocket/Domain.fs

@ -5,14 +5,19 @@
module Domain = module Domain =
open System.Drawing open System.Drawing
open SkiaSharp
/// The specification which uses System.Drawing brush to draw a grid. /// The specification used to note the orignial file's location and the
/// changes the user would like to make to it. (including the save
/// location of the modified version). Use this spec if you are using
/// System.Drawing.
type BrushSpec = type BrushSpec =
{ /// The original path of the image which the grid is being added to. { /// The original path of the image which the grid is being added to.
originalPath: string originalPath: string
/// The location of the new gridded image. /// The location of the new gridded image.
savePath: string savePath: string
/// The (System.Drawing) brush used to draw the grid. This determines the colour. /// The (System.Drawing) brush used to draw the grid.
/// This determines the colour of the grid.
colour: Brush colour: Brush
/// The thickness of the line on the grid. /// The thickness of the line on the grid.
penWidth: float32 penWidth: float32
@ -21,8 +26,11 @@
///The number of columns the grid will have. ///The number of columns the grid will have.
columns: int } columns: int }
/// The specification which uses includes individual RGBA values to /// The specification used to note the orignial file's location and the
/// draw a grid. /// changes the user would like to make to it (including the save
/// location of the modified version). This specification includes
/// individual RGBA values to describe the grid's colour. Use this spec.
/// if you are using System.Drawing.
type RGBASpec = type RGBASpec =
{ /// The original path of the image which the grid is being added to. { /// The original path of the image which the grid is being added to.
originalPath: string originalPath: string
@ -42,4 +50,48 @@
/// The number of rows the grid will have. /// The number of rows the grid will have.
rows: int rows: int
///The number of columns the grid will have. ///The number of columns the grid will have.
columns: int }
/// The specification used to note the orignial file's location and the
/// changes the user would like to make to it (including the save
/// location of the modified version). Use this spec. if you are using
/// the Skia-Sharp library.
type SkiaSpec =
{ /// The original path of the image which the grid is being added to.
originalPath: string
/// The location of the new gridded image.
savePath: string
/// The (SkiaSharp) colour used to draw the grid.
skColour: SKColor
/// The thickness of the line on the grid.
penWidth: float32
/// The number of rows the grid will have.
rows: int
///The number of columns the grid will have.
columns: int }
/// The specification used to note the orignial file's location and the
/// changes the user would like to make to it (including the save
/// location of the modified version). This specification includes
/// individual RGB values to describe the grid's colour. Use this spec.
/// if you are using the Skia-Sharp library.
type SkiaRGBSpec =
{ /// The original path of the image which the grid is being added to.
originalPath: string
/// The location of the new gridded image.
savePath: string
/// The amount of red (RGB) the grid's line will have.
/// (0 = no red, 255 = red turned up to eleven).
red: float32
/// The amount of green (RGB) the grid's line will have.
/// (0 = no green, 255 = green turned up to eleven).
green: float32
/// The amount of blue (RGB) the grid's line will have.
/// (0 = no blue, 255 = blue turned up to eleven).
blue: float32
/// The thickness of the line on the grid.
penWidth: float32
/// The number of rows the grid will have.
rows: int
///The number of columns the grid will have.
columns: int } columns: int }

151
DeathSocket/GridPainter.fs

@ -4,18 +4,51 @@ namespace DeathSocket
open ColourServices open ColourServices
/// Provides functions which help draw gridded overlays onto images. /// Provides functions which help draw gridded overlays onto images.
/// Grid Painter, and all of Death Socket, uses the System.Drawing brushes/colours. /// Death Socket, uses System.Drawing's brushes and colours.
/// If you are using System.Media brushes and colour, you will need to convert them. /// If you are using System.Media brushes and colour, you will need to
/// convert them. Death Socket, also, uses SkiaSharp for cross platform
/// functionality. If you are using Death Socket on Windows Desktop, use
/// functions which do not include "Skia" in their name. If you are using
/// Death Socket in a Xamarin/UWP project you should use the SkiaSharp
/// functions.
module GridPainter = module GridPainter =
open Validation open Validation
open ImageServices open ImageServices
// System.Drawing Functions
// ========================================================================
/// <summary>
/// Determines the (Pen) points needed to draw the appropriate number
/// of horizontal lines (I.E. rows). Each item in the array includes a
/// start and end co-ordinate (point) for each line.
/// Use this function when targeting .Net/Mono).
/// </summary>
/// <param name="width">The width of the image.</param>
/// <param name="height">The height of the image.</param>
/// <param name="rows">The number of rows the grid should have.</param>
/// <remarks>You will probably only need these when dealing with GUI's.</remarks>
let determineHorizontalLines (width: int) (height: int) (rows: int) =
createHorizontalLines width height rows
/// <summary>
/// Determines the (Pen) points needed to draw the appropriate number
/// of vertical lines (I.E. columns). Each item in the array includes a
/// start and end co-ordinate (point) for each line.
/// Use this function when targeting Windows Desktop (or Mono).
/// </summary>
/// <param name="width">The width of the image.</param>
/// <param name="height">The height of the image.</param>
/// <param name="columns">The number of columns the grid should have.</param>
/// <remarks>You will probably only need these when dealing with GUI's.</remarks>
let determineVerticalLines (width: int) (height: int) (columns: int) =
createVerticalLines width height columns
/// <summary> /// <summary>
/// Uses the information included in spec to create a gridded image. /// Uses the information included in spec to create a gridded image.
/// It then asynchronously saves it. /// It then asynchronously saves it. Uses .jpg or .png formats only.
/// Please stick to .bmp, .jpg or .png files. /// Use this function when targeting .Net/Mono).
/// The other (image) file types have not been tested.
/// </summary> /// </summary>
/// <param name="spec"> /// <param name="spec">
/// The specification used to generate the new gridded image /// The specification used to generate the new gridded image
@ -33,7 +66,7 @@ namespace DeathSocket
async { async {
try try
validateFilePath spec.originalPath |> ignore validateFilePath spec.originalPath |> ignore
validatFileType spec.savePath |> ignore validateSaveFileType spec.savePath |> ignore
drawBrushSpecGrid spec |> ignore drawBrushSpecGrid spec |> ignore
with with
| :? FileNotFoundException as ex -> | :? FileNotFoundException as ex ->
@ -42,8 +75,8 @@ namespace DeathSocket
/// <summary> /// <summary>
/// Uses the information included in spec to create a gridded image. It /// Uses the information included in spec to create a gridded image. It
/// then asynchronously saves it. Please stick to .bmp, .jpg or .png /// then asynchronously saves it. Uses .jpg or .png formats only.
/// files. The other (image) file types have not been tested. /// Use this function when targeting .Net/Mono).
/// </summary> /// </summary>
/// <param name="spec"> /// <param name="spec">
/// The specification used to generate the gridded image. /// The specification used to generate the gridded image.
@ -61,7 +94,7 @@ namespace DeathSocket
async { async {
try try
validateFilePath spec.originalPath |> ignore validateFilePath spec.originalPath |> ignore
validatFileType spec.savePath |> ignore validateSaveFileType spec.savePath |> ignore
drawRGBAGrid spec drawRGBAGrid spec
with with
| :? FileNotFoundException as ex -> | :? FileNotFoundException as ex ->
@ -70,6 +103,7 @@ namespace DeathSocket
/// <summary> /// <summary>
/// Creates a Sytsem.Drawing SolidBrush from the individual RGBA values. /// Creates a Sytsem.Drawing SolidBrush from the individual RGBA values.
/// Use this function when targeting .Net/Mono).
/// </summary> /// </summary>
/// <param name="r">The red value.</param> /// <param name="r">The red value.</param>
/// <param name="g">The green value.</param> /// <param name="g">The green value.</param>
@ -79,10 +113,12 @@ namespace DeathSocket
/// Death Socket uses System.Drawing and not System.Media for colours /// Death Socket uses System.Drawing and not System.Media for colours
/// and brushes. /// and brushes.
/// </remarks> /// </remarks>
let makeSolidBrushFromRGBA r g b a = makeBrushFromRGBA r g b a let makeSolidBrushFromRGBA (r: int) (g: int) (b:int) (a: int) =
makeBrushFromRGBA r g b a
/// <summary> /// <summary>
/// Creates a System.Drawing SolidBrush from a RGBASpec. /// Creates a System.Drawing SolidBrush from a RGBASpec.
/// Use this function when targeting .Net/Mono).
/// </summary> /// </summary>
/// <param name="spec"> /// <param name="spec">
///The specification which the brush is made from. ///The specification which the brush is made from.
@ -91,28 +127,97 @@ namespace DeathSocket
/// Death Socket uses System.Drawing and not System.Media for colours /// Death Socket uses System.Drawing and not System.Media for colours
/// and brushes. /// and brushes.
/// </remarks> /// </remarks>
let makeSolidBrushFromRGBASpec spec = makeBrushFromRGBASpec spec let makeSolidBrushFromRGBASpec (spec: RGBASpec) =
makeBrushFromRGBASpec spec
// SkiaSharp Functions
// ========================================================================
// NOT TESTED
/// <summary> /// <summary>
/// Determines the (Pen) points needed to draw the appropriate number of horizontal lines (I.E. rows). /// Determines the (SKPoints) points needed to draw the appropriate
/// Each item in the array includes a start and end co-ordinate (point) for each line. /// number of horizontal lines (I.E. rows). Each item in the array
/// included a start and end co-ordinate (SKPoint) for each line.
/// Use this function when targeting Xamarin/UWP/.Net Core (SkiaSharp).
/// </summary> /// </summary>
/// <param name="width">The width of the image.</param> /// <param name="width">The width of the image.</param>
/// <param name="height">The height of the image.</param> /// <param name="height">The height of the image.</param>
/// <param name="rows">The number of rows the grid should have.</param> /// <param name="rows">The number of rows the grid should have.</param>
/// <remarks>You will probably only need these when dealing with GUI's.</remarks> /// <remarks>This function is part of the SkiaSharp functions provided
let determineHorizontalLines width height rows = /// by Death Socket.</remarks>
createHorizontalLines width height rows let determineSKHorizontalLines (width: int) (height: int) (rows: int) =
createSKHorizontalLines width height rows
// NOT TESTED
/// <summary> /// <summary>
/// Determines the (Pen) points needed to draw the appropriate number of vertical lines (I.E. columns). /// Determines the (SKPoints) points needed to draw the appropriate
/// Each item in the array includes a start and end co-ordinate (point) for each line. /// number of vertical lines (I.E. columns). Each item in the array
/// included a start and end co-ordinate (SKPoint) for each line.
/// Use this function when targeting Xamarin/UWP/.Net Core (SkiaSharp).
/// </summary> /// </summary>
/// <param name="width">The width of the image.</param> /// <param name="width">The width of the image.</param>
/// <param name="height">The height of the image.</param> /// <param name="height">The height of the image.</param>
/// <param name="columns">The number of columns the grid should have.</param> /// <param name="columns">The number of columns the grid should have.
/// <remarks>You will probably only need these when dealing with GUI's.</remarks> /// </param>
let determineVerticalLines width height columns = /// <remarks>This function is part of the SkiaSharp functions provided
createVerticalLines width height columns /// by Death Socket.</remarks>
let determineSKVerticalLines (width: int) (height: int) (columns: int) =
createSKVerticalLines width height columns
// NOT TESTED
/// <summary>
/// Uses the information included in spec to create a gridded image.
/// It then asynchronously saves it. Uses .jpg or .png formats only.
/// Use this function when targeting Xamarin/UWP/.Net Core.
/// </summary>
/// <param name="spec">
/// Used to note the orignial file's location and the
/// changes the user would like to make to it (including the save
/// location of the modified version).
/// </param>
/// <remarks>
/// Make sure the image, which is having the overlay added to it,
/// is not in use or needed by another program/process.
/// This is because it is locked whilst in this function.
/// </remarks>
let applySkiaGridAsync (spec: SkiaSpec) =
async {
try
validateFilePath spec.originalPath |> ignore
validateSaveFileType spec.savePath |> ignore
drawSkiaGrid spec
with
| :? FileNotFoundException as ex ->
printfn "File could not be found at %s" ex.Message
}
// NOT TESTED
let drawskia () = drawSkiaGrid () /// <summary>
/// Uses the information included in spec to create a gridded image.
/// It then asynchronously saves it. Uses .jpg or .png formats only.
/// Use this function when targeting Xamarin/UWP/.Net Core.
/// </summary>
/// <param name="spec">
/// Used to note the orignial file's location and the
/// changes the user would like to make to it (including the save
/// location of the modified version).
/// </param>
/// <remarks>
/// Make sure the image, which is having the overlay added to it,
/// is not in use or needed by another program/process.
/// This is because it is locked whilst in this function.
/// </remarks>
let applySkiaRGBGridAsync (spec: SkiaRGBSpec) =
async {
try
validateFilePath spec.originalPath |> ignore
validateSaveFileType spec.savePath |> ignore
drawSkiaRGBGrid spec
with
| :? FileNotFoundException as ex ->
printfn "File could not be found at %s" ex.Message
}

147
DeathSocket/ImageServices.fs

@ -7,6 +7,101 @@
open ColourServices open ColourServices
open SkiaSharp open SkiaSharp
// SkiaSharp Functions
// ========================================================================
let createSKHorizontalLines width height rows =
let interval = float32 (height / rows)
[|for point in 1 .. (rows - 1) ->
[| SKPoint ((float32 0), (interval * (float32 point)))
SKPoint ((float32 width), (interval * (float32 point)))|]|]
let createSKVerticalLines width height columns =
let interval = float32 (width / columns)
[| for point in 1 .. (columns - 1) ->
[| SKPoint ((interval * (float32 point)), (float32 0))
SKPoint ((interval * (float32 point)), (float32 height))|]|]
let drawSkiaGrid (spec: SkiaSpec) =
use fileStream = File.Open (spec.originalPath, FileMode.Open)
use skStream = new SKManagedStream (fileStream)
use bitmap = SKBitmap.Decode (skStream)
use shader =
SKShader.CreateBitmap (bitmap, SKShaderTileMode.Mirror, SKShaderTileMode.Mirror)
let imageInfo = new SKImageInfo (bitmap.Width, bitmap.Height)
use surface = SKSurface.Create (imageInfo)
use canvas = surface.Canvas
canvas.Clear (SKColors.White)
use imageFill = new SKPaint ()
imageFill.Style <- SKPaintStyle.Fill
imageFill.Shader <- shader
canvas.DrawPaint (imageFill)
use stroke = new SKPaint ()
stroke.Style <- SKPaintStyle.Stroke
stroke.StrokeWidth <- spec.penWidth
stroke.Color <- spec.skColour
let horizontalLines =
createSKHorizontalLines (bitmap.Width) (bitmap.Height) (spec.rows)
let verticalLines =
createSKVerticalLines (bitmap.Width) (bitmap.Height) (spec.columns)
for hLine in horizontalLines do
canvas.DrawLine (hLine.[0], hLine.[1], stroke)
for vLine in verticalLines do
canvas.DrawLine (vLine.[0], vLine.[1], stroke)
use snapshot = surface.Snapshot ()
use data =
match Path.GetExtension (spec.savePath) with
| ".jpg" | ".JPG" -> snapshot.Encode (SKEncodedImageFormat.Jpeg, 100)
| ".png"| ".PNG" -> snapshot.Encode (SKEncodedImageFormat.Png, 100)
| _ -> invalidArg "savePath" "The file type must be a .jpg or .png file."
use saveStream = File.OpenWrite (spec.savePath)
data.SaveTo (saveStream)
let drawSkiaRGBGrid spec =
use fileStream = File.Open (spec.originalPath, FileMode.Open)
use skStream = new SKManagedStream (fileStream)
use bitmap = SKBitmap.Decode (skStream)
use shader =
SKShader.CreateBitmap (bitmap, SKShaderTileMode.Mirror, SKShaderTileMode.Mirror)
let imageInfo = new SKImageInfo (bitmap.Width, bitmap.Height)
use surface = SKSurface.Create (imageInfo)
use canvas = surface.Canvas
canvas.Clear (SKColors.White)
use imageFill = new SKPaint ()
imageFill.Style <- SKPaintStyle.Fill
imageFill.Shader <- shader
canvas.DrawPaint (imageFill)
use stroke = new SKPaint ()
stroke.Style <- SKPaintStyle.Stroke
stroke.StrokeWidth <- spec.penWidth
stroke.Color <-
new SKColor ((byte spec.red), (byte spec.green), (byte spec.blue))
let horizontalLines =
createSKHorizontalLines (bitmap.Width) (bitmap.Height) (spec.rows)
let verticalLines =
createSKVerticalLines (bitmap.Width) (bitmap.Height) (spec.columns)
for hLine in horizontalLines do
canvas.DrawLine (hLine.[0], hLine.[1], stroke)
for vLine in verticalLines do
canvas.DrawLine (vLine.[0], vLine.[1], stroke)
use snapshot = surface.Snapshot ()
use data =
match Path.GetExtension (spec.savePath) with
| ".jpg" | ".JPG" -> snapshot.Encode (SKEncodedImageFormat.Jpeg, 100)
| ".png"| ".PNG" -> snapshot.Encode (SKEncodedImageFormat.Png, 100)
| _ -> invalidArg "savePath" "The file type must be a .jpg or .png file."
use saveStream = File.OpenWrite (spec.savePath)
data.SaveTo (saveStream)
// System.Drawing Functions
// ========================================================================
let createHorizontalLines width height rows = let createHorizontalLines width height rows =
let interval = height / rows let interval = height / rows
[| for point in 1 .. (rows - 1) -> [| for point in 1 .. (rows - 1) ->
@ -19,7 +114,7 @@
[| Point ((interval * point), 0) [| Point ((interval * point), 0)
Point ((interval * point), height)|]|] Point ((interval * point), height)|]|]
(* Note on Use of Temp File in Functions which Add A Grid Overlay (* Note on Use of Temp. File in Functions which Add A Grid Overlay
=========================================================================== ===========================================================================
The temp. file is used in the functions below are there to convert images The temp. file is used in the functions below are there to convert images
with indexed pixels. Instead of listing them all, just assume any function with indexed pixels. Instead of listing them all, just assume any function
@ -53,52 +148,4 @@
createVerticalLines (clone.Size.Width) (clone.Size.Height) (spec.columns) createVerticalLines (clone.Size.Width) (clone.Size.Height) (spec.columns)
for line in horizontalLines do graphics.DrawLines (pen, line) for line in horizontalLines do graphics.DrawLines (pen, line)
for line in verticalLines do graphics.DrawLines (pen, line) for line in verticalLines do graphics.DrawLines (pen, line)
clone.Save (spec.savePath) clone.Save (spec.savePath)
// You are up to here. Need to draw lines and add image.
let drawSkiaGrid () =
// Set Canvas/Surface
let imageInfo = new SKImageInfo (2592, 1456)
use surface = SKSurface.Create(imageInfo)
let canvas = surface.Canvas
canvas.Clear (SKColors.White)
// Set SKPaint Objects
use stroke = new SKPaint ()
stroke.Style <- SKPaintStyle.Stroke
stroke.StrokeWidth <- float32 3
//stroke.Color <- SKColors.BlueViolet
stroke.Color <- makeSkiaColour 123 123 123
// Note about generating colours in Skia Sharp.
//stroke.Color <- new SKColor (byte 1000, byte 5111, byte 4225, byte 255)
use imageFill = new SKPaint ()
imageFill.Style <- SKPaintStyle.Fill
// Add Bitmap
let fileStream = File.Open (@"C:\Users\craig\Desktop\test.jpg", FileMode.Open)
use skStream = new SKManagedStream (fileStream)
use bitmap = SKBitmap.Decode (skStream)
use shader = SKShader.CreateBitmap (bitmap, SKShaderTileMode.Mirror, SKShaderTileMode.Mirror)
imageFill.Shader <- shader
canvas.DrawPaint (imageFill)
// Draw Lines
let horizontalLines = createHorizontalLines 2592 1456 6
let verticalLines = createVerticalLines 2592 1456 9
for hLine in horizontalLines do
let x1 = float32 hLine.[0].X
let y1 = float32 hLine.[0].Y
let x2 = float32 hLine.[1].X
let y2 = float32 hLine.[1].Y
canvas.DrawLine (x1, y1, x2, y2, stroke)
for vLine in verticalLines do
let x1 = float32 vLine.[0].X
let y1 = float32 vLine.[0].Y
let x2 = float32 vLine.[1].X
let y2 = float32 vLine.[1].Y
canvas.DrawLine (x1, y1, x2, y2, stroke)
use snapshot = surface.Snapshot ()
use data = snapshot.Encode (SKEncodedImageFormat.Png, 100)
use saveStream = File.OpenWrite (@"C:\Users\craig\Desktop\test-complete.jpg")
data.SaveTo (saveStream)
printfn "Skia Sharp image saved."

8
DeathSocket/Validation.fs

@ -7,14 +7,10 @@
| true -> () | true -> ()
| false -> raise (new FileNotFoundException (path + " could not be found.")) | false -> raise (new FileNotFoundException (path + " could not be found."))
let validatFileType file = let validateSaveFileType file =
match Path.GetExtension file with match Path.GetExtension file with
| ".bmp" -> ()
| ".BMP" -> ()
| ".jpg" -> () | ".jpg" -> ()
| ".JPG" -> () | ".JPG" -> ()
| ".png" -> () | ".png" -> ()
| ".PNG" -> () | ".PNG" -> ()
| ".tif" -> () | _ -> invalidArg "savePath" "The file type must be a .jpg or .png file."
| ".TIF" -> ()
| _ -> invalidArg "savePath" "The file type must be a .bmp, .jpg, .png or .tif file."

33
DeathSocketCLI/Commands.fs

@ -1,6 +1,7 @@
namespace Commands namespace Commands
module ConsoleCommands = module ConsoleCommands =
open System open System
open DeathSocket.GridPainter open DeathSocket.GridPainter
open DeathSocketCLI.Validation open DeathSocketCLI.Validation
@ -92,6 +93,34 @@
let lc () =``list-colours`` () let lc () =``list-colours`` ()
let``skia-test`` () = (* SkiaSharp Command-Methods -- NOT FOR MASS CONSUMPTION
drawskia () =======================================================================
These command-methods will not show up in the help section. These
command-methods are here for testing purposes. They mimic the command-
methods above, apart from using SkiaSharp. So, including these command-
methods will create a sense of duplicated functionality. Seeing as you
are reading this, it is assumed you can understand it. If so, please
feel free to use them -- just keep their exposure to a minimum.*)
// NOT TESTED
let ``list-skia-colours`` () =
printfn "[INFO.] Listing available SkiaSharp colours..."
for item in skiaColourList do
printfn "%s" item.Key
showEndOfCommandMessage
// NOT TESTED
let``add-skia-grid`` imgPath numRows numColumns pWidth colour newPath =
printfn "[INFO.] Adding SkiaSharp grid to image..."
buildSkiaSpec imgPath numRows numColumns pWidth colour newPath
|> applySkiaGridAsync
|> Async.Start
showEndOfCommandMessage
// NOT TESTED
let``add-skia-rgb-grid`` imgPath numRows numColumns pWidth r g b newPath =
printfn "[INFO.] Adding SkiaSharp grid to image..."
buildSkiaRGBSpec imgPath numRows numColumns pWidth r g b newPath
|> applySkiaRGBGridAsync
|> Async.Start
showEndOfCommandMessage showEndOfCommandMessage

79
DeathSocketCLI/Validation.fs

@ -4,6 +4,19 @@
open System.Drawing open System.Drawing
open System open System
open System.IO open System.IO
open SkiaSharp
(* This function creates a consistent line width amoung different image
sizes. Use this when the user has no means to specify a pen width. *)
let setPenWidth imgWidth imgHeight =
let width = float32 imgWidth
let height = float32 imgHeight
if (width >= height) then
height * (float32 0.002)
else width * (float32 0.002)
// System.Drawing Functions
// ========================================================================
let colourList = let colourList =
[ "blue", Brushes.AliceBlue [ "blue", Brushes.AliceBlue
@ -32,16 +45,7 @@
(String.Concat("The colour specifed is invalid.\n", (String.Concat("The colour specifed is invalid.\n",
"Please use the 'list-colours' command to see what you can use.")) "Please use the 'list-colours' command to see what you can use."))
(* This function creates a consistent line width amoung different image let buildSpec (imgPath) (numRows) (numColumns) (pWidth) (colour) (newPath) : BrushSpec =
sizes. Use this when the user has no means to specify a pen width. *)
let setPenWidth imgWidth imgHeight =
let width = float32 imgWidth
let height = float32 imgHeight
if (width >= height) then
height * (float32 0.002)
else width * (float32 0.002)
let buildSpec imgPath numRows numColumns pWidth colour newPath =
{ originalPath = imgPath { originalPath = imgPath
savePath = newPath savePath = newPath
colour = parseColour colour colour = parseColour colour
@ -52,13 +56,60 @@
let buildDefaultSpec imgPath newPath = let buildDefaultSpec imgPath newPath =
use stream = new FileStream (imgPath, FileMode.Open) use stream = new FileStream (imgPath, FileMode.Open)
use image = Image.FromStream (stream, false, false) use image = Image.FromStream (stream, false, false)
let spec = let spec : BrushSpec =
{ originalPath = imgPath { originalPath = imgPath
savePath = newPath savePath = newPath
colour = Brushes.White colour = Brushes.White
penWidth = setPenWidth (image.Width) (image.Height) penWidth = setPenWidth (image.Width) (image.Height)
rows = 10 rows = 10
columns = 10 } columns = 10 }
stream.Dispose () spec
image.Dispose ()
spec // SkiaSharp Functions
// ========================================================================
let skiaColourList =
[ "blue", SKColors.AliceBlue
"brown", SKColors.Brown
"black", SKColors.Black
"gray", SKColors.Gray
"grey", SKColors.Gray
"green", SKColors.Green
"purple", SKColors.Purple
"red", SKColors.Red
"white", SKColors.White
"yellow", SKColors.Yellow ]
|> Map.ofList
let isSkiaColourValid (colour: string) =
skiaColourList
|> Map.containsKey (colour.ToLower())
let parseSkiaColour colour =
match (isSkiaColourValid colour) with
| true ->
skiaColourList
|> Map.find (colour.ToLower())
| false ->
invalidArg "Colour"
(String.Concat("The colour specifed is invalid.\n",
"Please use the 'list-skia-colours' command to see what you can use."))
let buildSkiaSpec imgPath numRows numColumns pWidth colour newPath =
let colour = parseSkiaColour colour
{ originalPath = imgPath
savePath = newPath
skColour = colour
penWidth = pWidth
rows = numRows
columns = numColumns }
let buildSkiaRGBSpec imgPath numRows numColumns pWidth r g b newPath =
{ originalPath = imgPath
savePath = newPath
red = (float32 r)
green = (float32 g)
blue = (float32 b)
penWidth = pWidth
rows = numRows
columns = numColumns }

Loading…
Cancel
Save