This script will allow you to create a simple cartoon face controlling a few parameters like the pupil size, nose size and level of smile. Used to create the cartoon face are System.Drawing.Graphics controls like FillEllipse, DrawCurve and DrawLine. The background color is somewhat selectable while the object colors are random.
 
Here are a couple examples from the script –
 
CartoonFace_20140322_170532
 
CartoonFace_20140314_184605
 
In a WinForm Form I defined the Form and set some default values.
 

Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

# Main Form
$mainForm = New-Object Windows.Forms.Form
$mainForm.Location = "200,200"
$mainForm.FormBorderStyle = "FixedDialog"
$mainForm.BackColor = "White"
$mainForm.Font = “Comic Sans MS,8.25"
$mainForm.Text = "Draw Cartoon Face"
$mainForm.size = "520,280"

# Global Values
$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
$global:pupilValue = 5
$global:eyebrowValue = 5
$global:noseValue = 5
$global:mouthValue = 8
$global:backgroundText = "Black"

 
I collected the object parameters with four TrackBar controls. The TrackBar is setup wiyh a Label to show the name and the values as the TrackBar is moved. I added Plus/Minus symbols to make it easy to see in what direction your changing the values.
 

# Pupil TrackBar
$pupilTrackBar = New-Object Windows.Forms.TrackBar
$pupilTrackBar.Location = "140,20"
$pupilTrackBar.Orientation = "Horizontal"
$pupilTrackBar.Width = 350
$pupilTrackBar.Height = 40
$pupilTrackBar.LargeChange = 5
$pupilTrackBar.SmallChange = 1
$pupilTrackBar.TickFrequency = 1
$pupilTrackBar.TickStyle = "TopLeft"
$pupilTrackBar.SetRange(1, 8)
$pupilTrackBar.Value = 3
$pupilTrackBarValue = 3
$pupilTrackBar.add_ValueChanged({
    $pupilTrackBarValue = $pupilTrackBar.Value
    $pupilTrackBarLabel.Text = "Pupil Size ($pupilTrackBarValue)"
    $global:pupilValue = $pupilTrackBarValue
})
$mainForm.Controls.add($pupilTrackBar)

# Pupil Labels
$pupilTrackBarLabel = New-Object System.Windows.Forms.Label 
$pupilTrackBarLabel.Location = "20,20"
$pupilTrackBarLabel.Size = "100,23"
$pupilTrackBarLabel.ForeColor = "MediumBlue"
$pupilTrackBarLabel.Text = "Pupil Size ($pupilTrackBarValue)"
$mainForm.Controls.Add($pupilTrackBarLabel)
$pupilTrackBarPlus = New-Object System.Windows.Forms.Label 
$pupilTrackBarPlus.Location = "490,20"
$pupilTrackBarPlus.Size = "15,23"
$pupilTrackBarPlus.ForeColor = "Red"
$pupilTrackBarPlus.Text = " +"
$mainForm.Controls.Add($pupilTrackBarPlus)
$pupilTrackBarMinus = New-Object System.Windows.Forms.Label 
$pupilTrackBarMinus.Location = "130,20"
$pupilTrackBarMinus.Size = "15,23"
$pupilTrackBarMinus.ForeColor = "Red"
$pupilTrackBarMinus.Text = "- "
$mainForm.Controls.Add($pupilTrackBarMinus)

 
A ComboBox control provides the selections for the background color.
 

# Background ComboBox
$backgroundComboBox = New-Object System.Windows.Forms.ComboBox
$backgroundComboBox.Location = "145,200"
$backgroundComboBox.Size = "120,20"
$backgroundComboBox.ForeColor = "Indigo"
$backgroundComboBox.BackColor = "White"
[void]$backgroundComboBox.items.add("Black")
[void]$backgroundComboBox.items.add("White")
[void]$backgroundComboBox.items.add("Random")         
$backgroundComboBox.SelectedIndex = 0
$mainForm.Controls.Add($backgroundComboBox)

# Background ComboBox Label
$backgroundComboBoxLabel = New-Object System.Windows.Forms.Label 
$backgroundComboBoxLabel.Location = "20,200"
$backgroundComboBoxLabel.Size = "100,23"
$backgroundComboBoxLabel.ForeColor = "MediumBlue"
$backgroundComboBoxLabel.Text = "Background Color"
$mainForm.Controls.Add($backgroundComboBoxLabel)

 
To complete the Form a couple buttons for the Draw and Exit actions are provided.
 

# Draw Button
$drawButton = New-Object System.Windows.Forms.Button 
$drawButton.Location = "320,200"
$drawButton.Size = "75,23"
$drawButton.ForeColor = "SeaGreen"
$drawButton.BackColor = "White"
$drawButton.Text = "Draw"
$drawButton.add_Click({DrawIt})
$mainForm.Controls.Add($drawButton)

# Exit Button
$exitButton = New-Object System.Windows.Forms.Button
$exitButton.Location = "405,200"
$exitButton.Size = "75,23"
$exitButton.ForeColor = "Red"
$exitButton.BackColor = "White"
$exitButton.Text = "Exit"
$exitButton.add_Click({$mainForm.close()})
$mainForm.Controls.Add($exitButton)

 
The Draw button calls the main drawing routine. I setup the output image and configure the background color depending on the selection made.
 

# Draw the Object
Function DrawIt {
$bitmap = New-Object System.Drawing.Bitmap(1024, 768)
$bitmapGraphics = [System.Drawing.Graphics]::FromImage($bitmap) 
$pen = New-Object Drawing.Pen "white"
# Image Background Color
If ($backgroundComboBox.Text -eq "Transparent") {
    $bitmap.MakeTransparent()
} Else {
    If ($backgroundComboBox.Text -eq "Random") {
        $red   = (Get-Random -minimum 0 -maximum 255)
        $green = (Get-Random -minimum 0 -maximum 255)
        $blue  = (Get-Random -minimum 0 -maximum 255)
        $backColor = [System.Drawing.Color]::FromArgb($red, $green, $blue)
        $bitmapGraphics.Clear($backColor)
    } Else {
        $bitmapGraphics.Clear($backgroundComboBox.Text)
    }
}

 
First the head is drawn. I set the Brush to a random color and draw it positioned relative to the outside edge. The individual objects are then drawn in the head. The selected value is replaced with the divisor used to position the object.
 

Function DrawHead {
    $red = (Get-Random -minimum 0 -maximum 255)
    $green = (Get-Random -minimum 0 -maximum 255)
    $blue = (Get-Random -minimum 0 -maximum 255)
    $brushColor = [System.Drawing.Color]::FromArgb($red, $green, $blue)
    $brush = New-Object System.Drawing.SolidBrush $brushColor
    $x = 1024/10
    $y = 768/10
    $width = 1024 - (1024/4)
    $height = 768 - (768/7)
    $bitmapGraphics.FillEllipse($brush, $x, $y, $width, $height)
}

Function DrawPupil {
    If ([int]$global:pupilValue -eq 1) {$value = 90}
    If ([int]$global:pupilValue -eq 2) {$value = 80}
    If ([int]$global:pupilValue -eq 3) {$value = 70}
    If ([int]$global:pupilValue -eq 4) {$value = 60}
    If ([int]$global:pupilValue -eq 5) {$value = 50}
    If ([int]$global:pupilValue -eq 6) {$value = 40}
    If ([int]$global:pupilValue -eq 7) {$value = 30}
    If ([int]$global:pupilValue -eq 8) {$value = 20}
    $red = (Get-Random -minimum 0 -maximum 255)
    $green = (Get-Random -minimum 0 -maximum 255)
    $blue = (Get-Random -minimum 0 -maximum 255)
    $brushColor = [System.Drawing.Color]::FromArgb($red, $green, $blue)
    $brush = New-Object System.Drawing.SolidBrush $brushColor
    $x1 = 1024/2.9
    $x2 = 1024/1.7
    $y = 768/2.7
    $width = 1024/$value
    $height = 768/$value
    $bitmapGraphics.FillEllipse($brush, $x1, $y, $width, $height)
    $bitmapGraphics.FillEllipse($brush, $x2, $y, $width, $height)
}

Function DrawNose {
    If ([int]$global:noseValue -eq 1)  {$value = 1.9}
    If ([int]$global:noseValue -eq 2)  {$value = 1.85}
    If ([int]$global:noseValue -eq 3)  {$value = 1.8}
    If ([int]$global:noseValue -eq 4)  {$value = 1.75}
    If ([int]$global:noseValue -eq 5)  {$value = 1.7}
    If ([int]$global:noseValue -eq 6)  {$value = 1.65}
    If ([int]$global:noseValue -eq 7)  {$value = 1.6}
    If ([int]$global:noseValue -eq 8)  {$value = 1.55}
    If ([int]$global:noseValue -eq 9)  {$value = 1.5}
    $red = (Get-Random -minimum 0 -maximum 255)
    $green = (Get-Random -minimum 0 -maximum 255)
    $blue = (Get-Random -minimum 0 -maximum 255)
    $penColor = [System.Drawing.Color]::FromArgb($red, $green, $blue)
    $pen = New-Object Drawing.Pen $penColor
    $pen.Width = 6
    $nose = @()
    $x1 = 1024/2.1
    $y1 = 768/2.3
    $x2 = 1024/$value
    $y2 = 768/1.6
    $x3 = 1024/2.2
    $y3 = 768/1.5
    $noseNext = New-Object System.Drawing.Point($x1, $y1)
    $nose += $noseNext
    $noseNext = New-Object System.Drawing.Point($x2, $y2)
    $nose += $noseNext
    $noseNext = New-Object System.Drawing.Point($x3, $y3)
    $nose += $noseNext
    $bitmapGraphics.DrawCurve($pen, $nose)

 
Finally the image is written to disk and displayed with the default image viewer.
 

$outFile = $scriptPath + "\"  + "CartoonFace_" + (Get-Date -UFormat %Y%m%d_%H%M%S) + ".bmp"
$bitmap.Save($outFile)
Invoke-Item $outFile

 
The objects are positioned within the Form relative placement to the Form edge. After working with this method I think greater flexibility and control would be derived by positioning the objects relative to the head boundaries. Maybe following the arc of the head ellipse and using a position along a radius. The head could then be repositioned or resized and keep the other objects relative to it. The current method allows the image to be resized but not the head individually.
 
CartoonFace
 
Download the complete script here – CartoonFace.ps1

Advertisements