Death Socket consists of three projects. They are a .Net Standard 2.0 library, a console program and a Test Centre. The purpose of this repository is to provide a way for people to add grids to images. https://www.craigoates.net/Software/project/13
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

169 lines
7.6 KiB

module internal ImageServices
open System.IO
open System.Drawing
open System.Drawing.Imaging
open DeathSocket
open ColourServices
open SkiaSharp
open System
let setLineThickness pDimension aDimension lineWidth =
if (pDimension <= 0.0 || aDimension <= 0.0 || lineWidth <= 0.0) then
raise (new DivideByZeroException ("[ERROR] The images height and width must be greater than 0."))
else lineWidth / (pDimension / aDimension)
// 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 determineSkiaDimensions filePath =
use fileStream = File.Open (filePath, FileMode.Open)
use skStream = new SKManagedStream (fileStream)
use bitmap = SKBitmap.Decode (skStream)
(bitmap.Width, bitmap.Height)
// Does not work when using SkiaSharp NuGet v. 1.68
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)
// Does not work when using SkiaSharp NuGet v. 1.68
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 interval = height / rows
[| for point in 1 .. (rows - 1) ->
[|Point (0, (interval * point))
Point (width, (interval * point) )|]|]
let createVerticalLines width height columns =
let interval = width / columns
[| for point in 1 .. (columns - 1) ->
[| Point ((interval * point), 0)
Point ((interval * point), height)|]|]
let determineSystemDrawingDimensions filePath =
use bitmap = Bitmap.FromFile filePath
(bitmap.Width, bitmap.Height)
(* 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
with indexed pixels. Instead of listing them all, just assume any function
with a "*Spec" type as a parameter will use this "temp" file. *)
let drawBrushSpecGrid (spec: BrushSpec) =
use original = Bitmap.FromFile spec.originalPath
use temp = new Bitmap(original)
use clone = temp.Clone(new Rectangle(0, 0, temp.Width, temp.Height), PixelFormat.Format32bppArgb)
use graphics = Graphics.FromImage(clone)
use pen = new Pen (spec.colour, width = spec.penWidth)
graphics.DrawImage(original,new Rectangle(0, 0, clone.Width, clone.Height))
let horizontalLines =
createHorizontalLines (clone.Size.Width) (clone.Size.Height) (spec.rows)
let verticalLines =
createVerticalLines (clone.Size.Width) (clone.Size.Height) (spec.columns)
for line in horizontalLines do graphics.DrawLines (pen, line)
for line in verticalLines do graphics.DrawLines (pen, line)
clone.Save (spec.savePath)
let drawRGBAGrid (spec: RGBASpec) =
use original = Bitmap.FromFile spec.originalPath
use temp = new Bitmap (original)
use clone = temp.Clone (new Rectangle(0, 0, temp.Width, temp.Height), PixelFormat.Format32bppArgb)
use graphics = Graphics.FromImage(clone)
use pen = new Pen ((makeBrushFromRGBASpec spec), width = spec.penWidth)
graphics.DrawImage (original,new Rectangle(0, 0, clone.Width, clone.Height))
let horizontalLines =
createHorizontalLines (clone.Size.Width) (clone.Size.Height) (spec.rows)
let verticalLines =
createVerticalLines (clone.Size.Width) (clone.Size.Height) (spec.columns)
for line in horizontalLines do graphics.DrawLines (pen, line)
for line in verticalLines do graphics.DrawLines (pen, line)
clone.Save (spec.savePath)