Craig Oates
6 years ago
6 changed files with 115 additions and 96 deletions
@ -0,0 +1,21 @@
|
||||
namespace SmoulderingBeachBall |
||||
|
||||
[<AutoOpen>] |
||||
module DomainTypes = |
||||
|
||||
open System.Drawing |
||||
|
||||
type OverlayType = |
||||
| Border |
||||
| Full |
||||
|
||||
type OverlaySpec = |
||||
{ colour: Brush; |
||||
overlayType: OverlayType } |
||||
|
||||
type ImageSpec = |
||||
{ width: int; |
||||
height: int; |
||||
colour: Brush; |
||||
filePath: string; |
||||
overlay: OverlaySpec option } |
@ -1,92 +0,0 @@
|
||||
namespace SmoulderingBeachBall |
||||
|
||||
module ImageMaker = |
||||
|
||||
open System |
||||
open System.IO |
||||
open System.Drawing |
||||
|
||||
type OverlayType = |
||||
| Border |
||||
| Full |
||||
|
||||
type OverlaySpec = |
||||
{ colour: Brush; |
||||
overlayType: OverlayType } |
||||
|
||||
type ImageSpec = |
||||
{ width: int; |
||||
height: int; |
||||
colour: Brush; |
||||
filePath: string; |
||||
overlay: OverlaySpec option } |
||||
|
||||
let private validateDimension dimension = |
||||
match dimension with |
||||
| dimension when dimension <= 0 -> invalidArg "dimension" "The width and height must be greater than 0." |
||||
| _ -> () |
||||
|
||||
let private validateDirectory filePath = |
||||
let path = Path.GetDirectoryName filePath |
||||
match (Directory.Exists path) with |
||||
| false -> invalidArg "filePath" "Unable to save to the specified location because it does not exist." |
||||
| true -> () |
||||
|
||||
let private penOffset penWidth = int (penWidth / (float32 2)) |
||||
|
||||
let private createBorderPath penWidth spec = |
||||
let offset = penOffset penWidth |
||||
[|Point (0, offset); // Essentially (0, 0) |
||||
Point ((spec.width - offset), offset); |
||||
Point ((spec.width - offset), (spec.height - offset)); |
||||
Point (offset, (spec.height - offset)); |
||||
Point (offset, 0)|] |
||||
|
||||
let private drawBorder (graphics: Graphics) (pen: Pen) spec = |
||||
printfn "[INFO.] Adding border to image..." |
||||
let penPath = createBorderPath pen.Width spec |
||||
graphics.DrawLines (pen, penPath) |
||||
|
||||
|
||||
let private drawFullOverlay (graphics: Graphics) (pen: Pen) spec = |
||||
drawBorder graphics pen spec |
||||
printfn "[INFO.] Adding full overlay to image..." |
||||
let offset = penOffset pen.Width |
||||
// Draws line from top-left to bottom-right of square. |
||||
graphics.DrawLine (pen, offset, offset, (spec.width - offset), (spec.height - offset)) |
||||
// Draws line from top-right to bottom-left of square. |
||||
graphics.DrawLine (pen, (spec.width - offset), offset, offset, (spec.height - offset)) |
||||
|
||||
let private addOverlayToImage graphics spec = |
||||
let overlay = spec.overlay.Value |
||||
let pen = new Pen (overlay.colour, Width = 10.0f) |
||||
match overlay.overlayType with |
||||
| Border -> drawBorder graphics pen spec |
||||
| Full -> drawFullOverlay graphics pen spec |
||||
|
||||
let private drawImage spec = |
||||
let bitmap = new Bitmap (spec.width, spec.height) |
||||
let graphics = Graphics.FromImage (bitmap) |
||||
let rectangle = Rectangle (0, 0, spec.width, spec.height) |
||||
graphics.FillRectangle (spec.colour, rectangle) |
||||
match spec.overlay.IsSome with |
||||
| true -> addOverlayToImage graphics spec |
||||
| false -> printfn "[INFO.] No overlay specified. Creating image without one." |
||||
bitmap.Save (spec.filePath) |
||||
bitmap.Dispose() |
||||
graphics.Dispose() |
||||
|
||||
let makeImage spec = |
||||
async { |
||||
try |
||||
printfn "[INFO.] Attempting to make image..." |
||||
validateDimension spec.width |
||||
validateDimension spec.height |
||||
validateDirectory spec.filePath |
||||
drawImage spec |
||||
printfn "[SUCCESS] Image creation attempt complete." |
||||
return () |
||||
with |
||||
| :? ArgumentException as ex -> printfn "%s" ex.Message |
||||
| _ as ex -> printfn "%s" ex.Message |
||||
} |
@ -0,0 +1,64 @@
|
||||
module internal InternalServices |
||||
|
||||
open System.IO |
||||
open System.Drawing |
||||
open SmoulderingBeachBall |
||||
|
||||
module Validation = |
||||
|
||||
let validateDimension dimension = |
||||
match dimension with |
||||
| dimension when dimension <= 0 -> invalidArg "dimension" "The width and height must be greater than 0." |
||||
| _ -> () |
||||
|
||||
let validateDirectory filePath = |
||||
let path = Path.GetDirectoryName filePath |
||||
match (Directory.Exists path) with |
||||
| false -> invalidArg "filePath" "Unable to save to the specified location because it does not exist." |
||||
| true -> () |
||||
|
||||
module Drawing = |
||||
|
||||
let penOffset penWidth = int (penWidth / (float32 2)) |
||||
|
||||
let createBorderPath penWidth spec = |
||||
let offset = penOffset penWidth |
||||
[|Point (0, offset); // Essentially (0, 0) |
||||
Point ((spec.width - offset), offset); |
||||
Point ((spec.width - offset), (spec.height - offset)); |
||||
Point (offset, (spec.height - offset)); |
||||
Point (offset, 0)|] |
||||
|
||||
let drawBorder (graphics: Graphics) (pen: Pen) spec = |
||||
printfn "[INFO.] Adding border to image..." |
||||
let penPath = createBorderPath pen.Width spec |
||||
graphics.DrawLines (pen, penPath) |
||||
|
||||
|
||||
let drawFullOverlay (graphics: Graphics) (pen: Pen) spec = |
||||
drawBorder graphics pen spec |
||||
printfn "[INFO.] Adding full overlay to image..." |
||||
let offset = penOffset pen.Width |
||||
// Draws line from top-left to bottom-right of square. |
||||
graphics.DrawLine (pen, offset, offset, (spec.width - offset), (spec.height - offset)) |
||||
// Draws line from top-right to bottom-left of square. |
||||
graphics.DrawLine (pen, (spec.width - offset), offset, offset, (spec.height - offset)) |
||||
|
||||
let addOverlayToImage graphics spec = |
||||
let overlay = spec.overlay.Value |
||||
let pen = new Pen (overlay.colour, Width = 10.0f) |
||||
match overlay.overlayType with |
||||
| Border -> drawBorder graphics pen spec |
||||
| Full -> drawFullOverlay graphics pen spec |
||||
|
||||
let drawImage spec = |
||||
let bitmap = new Bitmap (spec.width, spec.height) |
||||
let graphics = Graphics.FromImage (bitmap) |
||||
let rectangle = Rectangle (0, 0, spec.width, spec.height) |
||||
graphics.FillRectangle (spec.colour, rectangle) |
||||
match spec.overlay.IsSome with |
||||
| true -> addOverlayToImage graphics spec |
||||
| false -> printfn "[INFO.] No overlay specified. Creating image without one." |
||||
bitmap.Save (spec.filePath) |
||||
bitmap.Dispose() |
||||
graphics.Dispose() |
@ -0,0 +1,22 @@
|
||||
namespace SmoulderingBeachBall |
||||
|
||||
module ImageMaker = |
||||
|
||||
open System |
||||
open InternalServices.Validation |
||||
open InternalServices.Drawing |
||||
|
||||
let makeImage (spec: ImageSpec) = |
||||
async { |
||||
try |
||||
printfn "[INFO.] Attempting to make image..." |
||||
validateDimension spec.width |
||||
validateDimension spec.height |
||||
validateDirectory spec.filePath |
||||
drawImage spec |
||||
printfn "[SUCCESS] Image creation attempt complete." |
||||
return () |
||||
with |
||||
| :? ArgumentException as ex -> printfn "%s" ex.Message |
||||
| _ as ex -> printfn "%s" ex.Message |
||||
} |
Loading…
Reference in new issue