Compare commits

...

6 Commits

Author SHA1 Message Date
Craig Oates bcbb731d41 update library build number to 2020.07.23.1. 4 years ago
Craig Oates 896130a11b update tests and Scratch Pad script. 4 years ago
Craig Oates 507da455bf add grey scale functionality to RGBASpec image type. 4 years ago
Craig Oates 3abf3d3cd7 stub-out drawRGBAGridGrey functionality. 4 years ago
Craig Oates 77f198ffcc refactor applyGridToImageAsync (utilise greyScale better). 4 years ago
Craig Oates b7cd421323 implement rough initial version of convert to greyscale. 4 years ago
  1. 10
      DeathSocket/DeathSocket.fsproj
  2. 14
      DeathSocket/GridPainter.fs
  3. 72
      DeathSocket/ImageServices.fs
  4. 12
      DeathSocket/ScratchPad.fsx
  5. 30
      DeathSocketCLI/Commands.fs
  6. 15
      TestCentre/LibraryTests.fs

10
DeathSocket/DeathSocket.fsproj

@ -4,7 +4,7 @@
<TargetFramework>netstandard2.0</TargetFramework>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
<Version>2.0.0.0</Version>
<Version>2020.07.23.1</Version>
<Authors>Craig Oates</Authors>
<Product>Death Socket</Product>
<Description>A .Net Standard library which you can plug into to project and draw gridded overlays onto you images. Please note, Death Socket uses System.Drawing brushes and not System.Media brushes.</Description>
@ -16,9 +16,9 @@
<RepositoryType>Git</RepositoryType>
<PackageTags>deathsocket grid image overlay f#</PackageTags>
<PackageReleaseNotes>A minor release. The change from 1.x to 2.x is to signify the changing of the projects versioning control system, from GitLab to git.abbether. The projects package information and its NuGet dependencies have been updated.</PackageReleaseNotes>
<AssemblyVersion>2.0.0.0</AssemblyVersion>
<AssemblyVersion>2020.07.23.1</AssemblyVersion>
<PackageIconUrl></PackageIconUrl>
<FileVersion>2.0.0.0</FileVersion>
<FileVersion>2020.07.23.1</FileVersion>
<DependsOnNETStandard>true</DependsOnNETStandard>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageIcon>death-socket-repo-logo.png</PackageIcon>
@ -32,7 +32,7 @@
<Compile Include="ImagePrep.fs" />
<Compile Include="ImageServices.fs" />
<Compile Include="GridPainter.fs" />
<None Include="..\..\..\_temp\death-socket-repo-logo.png">
<None Include="..\..\..\_projects\death-socket\death-socket-repo-logo.png">
<Pack>True</Pack>
<PackagePath></PackagePath>
</None>
@ -46,7 +46,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Update="FSharp.Core" Version="4.7.0" />
<PackageReference Update="FSharp.Core" Version="4.7.2" />
</ItemGroup>
</Project>

14
DeathSocket/GridPainter.fs

@ -34,22 +34,26 @@ namespace DeathSocket
/// is not in use or needed by another program/process.
/// This is because it is locked whilst in this function.
/// </remarks>
let applyGridToImageAsync (spec: ImageSpec) =
let applyGridToImageAsync (makeGreyScale: bool) (spec: ImageSpec) =
async {
try
match spec with
| Brush b ->
validateIO b.originalPath b.savePath |> ignore
drawBrushSpecGrid b
match makeGreyScale with
| true -> drawBrushSpecGridGrey b
| false -> drawBrushSpecGrid b
| RGBA r ->
validateIO r.originalPath r.savePath |> ignore
drawRGBAGrid r
match makeGreyScale with
| true -> drawRGBAGridGrey r
| false -> drawRGBAGrid r
| Skia s ->
validateIO s.originalPath s.savePath |> ignore
drawSkiaGrid s
drawSkiaGrid s // greyScale not implemented
| SkiaRGB sR ->
validateIO sR.originalPath sR.savePath |> ignore
drawSkiaRGBGrid sR
drawSkiaRGBGrid sR // greyScale not implemented
| _ -> printfn "[DEATH SOCKET INFO] Inappropriate ImageSpec used here. Please use none buffer-based spec's when using this function."
with
| :? FileNotFoundException as ex ->

72
DeathSocket/ImageServices.fs

@ -191,14 +191,45 @@
assume any function with a "*Spec" type as a parameter will use this "temp"
file. *)
let drawBrushSpecGridGrey (spec: BrushSpec) =
(* Found this code for this function at:
https://stackoverflow.com/questions/199468/c-sharp-image-clone-out-of-memory-exception *)
use original = Bitmap.FromFile spec.originalPath
use temp = new Bitmap(original)
use clone = new Bitmap(temp.Width, temp.Height)
use g = Graphics.FromImage(clone)
let aM: float32[][] = [|
[| (float32 0.3); (float32 0.3); (float32 0.3); (float32 0.0); (float32 0.0) |];
[| (float32 0.59); (float32 0.59); (float32 0.59); (float32 0.0); (float32 0.0) |];
[| (float32 0.11); (float32 0.11); (float32 0.11); (float32 0.0); (float32 0.0) |];
[| (float32 0.0); (float32 0.0); (float32 0.0); (float32 1.0); (float32 0.0) |];
[| (float32 0.0); (float32 0.0); (float32 0.0); (float32 0.0); (float32 1.0) |];
|]
let colourMatrix = new ColorMatrix(aM)
use attributes = new ImageAttributes()
attributes.SetColorMatrix(colourMatrix)
g.DrawImage(temp, new Rectangle(0, 0, temp.Width, temp.Height),
0, 0, temp.Width, temp.Height, GraphicsUnit.Pixel, attributes)
use graphics = Graphics.FromImage(clone)
use pen = new Pen (spec.colour, width = spec.penWidth)
graphics.DrawImage(clone ,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 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 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))
graphics.DrawImage(clone ,new Rectangle(0, 0, clone.Width, clone.Height))
let horizontalLines =
createHorizontalLines (clone.Size.Width) (clone.Size.Height) (spec.rows)
let verticalLines =
@ -221,4 +252,39 @@
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 drawRGBAGridGrey (spec: RGBASpec) =
// This part converts the images to greyscale.
use original = Bitmap.FromFile spec.originalPath
use temp = new Bitmap (original)
use clone = new Bitmap(temp.Width, temp.Height)
use g = Graphics.FromImage(clone)
// This can be refactored out into its own function or reachable from
// anywhere in this module. It's used more than once and doesn't use 'use'.
let aM: float32[][] = [|
[| (float32 0.3); (float32 0.3); (float32 0.3); (float32 0.0); (float32 0.0) |];
[| (float32 0.59); (float32 0.59); (float32 0.59); (float32 0.0); (float32 0.0) |];
[| (float32 0.11); (float32 0.11); (float32 0.11); (float32 0.0); (float32 0.0) |];
[| (float32 0.0); (float32 0.0); (float32 0.0); (float32 1.0); (float32 0.0) |];
[| (float32 0.0); (float32 0.0); (float32 0.0); (float32 0.0); (float32 1.0) |];
|]
let colourMatrix = new ColorMatrix(aM) // Maybe put in own function?
use attributes = new ImageAttributes()
attributes.SetColorMatrix(colourMatrix)
g.DrawImage(temp, new Rectangle(0, 0, temp.Width, temp.Height),
0, 0, temp.Width, temp.Height, GraphicsUnit.Pixel, attributes)
use graphics = Graphics.FromImage(clone)
// This part applies the grid.
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)

12
DeathSocket/ScratchPad.fsx

@ -51,6 +51,10 @@ let dimensions =
// Change the line thickness (the last parameter) to whatever you want.
let scaledPen = GridPainter.scaleLineThickness (100, 100) dimensions 8.0
(* THE CODE BELOW DOES NOT INCLUDE THE GREY SCALE FUNCTIONALITY.
I HAVE JUST PLACE 'FALSE' IN PLACE. THE GREY SCALE OPTIONS WILL NEED ADDING
AT SOME POINT. WHEN THAT IS DONE, DELETE THIS COMMENT.*)
// Brush Specification (uses System.Drawing)
Brush ({ originalPath = desktop + "/test.jpg"
savePath = desktop + "/grid.png"
@ -58,7 +62,7 @@ Brush ({ originalPath = desktop + "/test.jpg"
penWidth = (float32 1)
rows = 10
columns = 10 })
|> GridPainter.applyGridToImageAsync
|> GridPainter.applyGridToImageAsync false
|> Async.Start
// RGBA Specification (uses System.Drawing)
@ -71,7 +75,7 @@ RGBA ({ originalPath = desktop + "/test.jpg"
penWidth = (float32 1)
rows = 10
columns = 10 })
|> GridPainter.applyGridToImageAsync
|> GridPainter.applyGridToImageAsync false
|> Async.Start
// Skia Specification (uses SkiaSharp -- use with Xamarin)
@ -81,7 +85,7 @@ Skia ({ originalPath = desktop + "/test.jpg"
penWidth = (float32 1)
rows = 10
columns = 10})
|> GridPainter.applyGridToImageAsync
|> GridPainter.applyGridToImageAsync false
|> Async.Start
// SkiaRGB Specification (uses SkiaSharp -- use with Xamarin)
@ -93,5 +97,5 @@ SkiaRGB ({ originalPath = desktop + "/test.jpg"
penWidth = (float32 1)
rows = 10
columns = 10})
|> GridPainter.applyGridToImageAsync
|> GridPainter.applyGridToImageAsync false
|> Async.Start

30
DeathSocketCLI/Commands.fs

@ -32,15 +32,15 @@
let exit () = Environment.Exit (Environment.ExitCode)
[<ListCommand>]
[<Parameters "(image-path: string) (new-path: string)">]
[<Parameters "(image-path: string) (new-path: string) (greyScale: bool)">]
[<Description
"Takes the image at 'image-path' applies a 10x10 grid (in white) to it and saves the result at 'new-path'.">]
[<Usage "add-default C:/base-image.png C:/final-image.png">]
let ``add-default`` imgPath newPath =
[<Usage "add-default C:/base-image.png C:/final-image.png true">]
let ``add-default`` imgPath newPath greyScale=
try
printfn "[INFO.] Adding default grid to image..."
Brush (buildDefaultSpec imgPath newPath)
|> applyGridToImageAsync
|> applyGridToImageAsync greyScale
|> Async.Start
showEndOfCommandMessage
with
@ -51,15 +51,15 @@
[<ListCommand>]
[<Parameters
("(image-path: string) (no-of-rows: int) (no-of-columns: int) " +
"(pen-width: float32) (colour: string) (new-path: string)")>]
"(pen-width: float32) (colour: string) (new-path: string) (greyScale: bool)")>]
[<Description "Adds a grid to an image, using the specified parameters, and saves it.">]
[<Usage
"add-grid C:/orignal-image.png 10 5 2 red C:/new-image.png">]
let ``add-grid`` imgPath numRows numColumns pWidth colour newPath =
"add-grid C:/orignal-image.png 10 5 2 red C:/new-image.png true">]
let ``add-grid`` imgPath numRows numColumns pWidth colour newPath greyScale =
try
printfn "[INFO.] Adding grid to image..."
Brush (buildSpec imgPath numRows numColumns pWidth colour newPath)
|> applyGridToImageAsync
|> applyGridToImageAsync greyScale
|> Async.Start
showEndOfCommandMessage
with
@ -87,10 +87,10 @@
hosted alongside the repository on GitHub.
URL: https://github.com/CraigOates/Death-Socket/wiki *)
let ad imgPath newPath = ``add-default`` imgPath newPath
let ad imgPath newPath greyScale = ``add-default`` imgPath newPath greyScale
let ag imgPath numRows numColumns pWidth colour newPath =
``add-grid`` imgPath numRows numColumns pWidth colour newPath
let ag imgPath numRows numColumns pWidth colour newPath greyScale =
``add-grid`` imgPath numRows numColumns pWidth colour newPath greyScale
let lc () = ``list-colours`` ()
@ -109,16 +109,16 @@
printfn "%s" item.Key
showEndOfCommandMessage
let``add-skia-grid`` imgPath numRows numColumns pWidth colour newPath =
let``add-skia-grid`` imgPath numRows numColumns pWidth colour newPath greyScale=
printfn "[INFO.] Adding SkiaSharp grid to image..."
Skia (buildSkiaSpec imgPath numRows numColumns pWidth colour newPath)
|> applyGridToImageAsync
|> applyGridToImageAsync greyScale // Not implement in this context.
|> Async.Start
showEndOfCommandMessage
let``add-skia-rgb-grid`` imgPath numRows numColumns pWidth r g b newPath =
let``add-skia-rgb-grid`` imgPath numRows numColumns pWidth r g b newPath greyScale =
printfn "[INFO.] Adding SkiaSharp grid to image..."
SkiaRGB (buildSkiaRGBSpec imgPath numRows numColumns pWidth r g b newPath)
|> applyGridToImageAsync
|> applyGridToImageAsync greyScale // Not implement in this context.
|> Async.Start
showEndOfCommandMessage

15
TestCentre/LibraryTests.fs

@ -73,6 +73,13 @@
Intended for horizontal and vertical line tests. *)
let newNum () = rand.Next(1, 1000)
// Used mostly for making the image grey scale when add a grid to it.
let newBool() =
let num = rand.NextDouble()
match num with
| x when num < 0.5 -> true
| _ -> false
let newPenWidth () = rand.Next (1, 10)
let newRGBANum () = rand.Next (255)
@ -134,7 +141,7 @@
penWidth = float32 (newPenWidth())
rows = 10
columns = 10 })
|> applyGridToImageAsync
|> applyGridToImageAsync (newBool())
|> Async.RunSynchronously
(File.Exists sPath) = true
@ -152,7 +159,7 @@
penWidth = float32 (newPenWidth())
rows = 10
columns = 10 })
|> applyGridToImageAsync
|> applyGridToImageAsync (newBool())
|> Async.RunSynchronously
(File.Exists sPath) = true
@ -199,7 +206,7 @@
penWidth = float32 (newPenWidth())
rows = newNum ()
columns = newNum () })
|> applyGridToImageAsync
|> applyGridToImageAsync (newBool())
|> Async.RunSynchronously
(File.Exists sPath) = true
@ -217,7 +224,7 @@
penWidth = float32 (newPenWidth())
rows = newNum ()
columns = newNum () })
|> applyGridToImageAsync
|> applyGridToImageAsync (newBool())
|> Async.RunSynchronously
(File.Exists sPath) = true

Loading…
Cancel
Save