Mostrando postagens com marcador GUI. Mostrar todas as postagens
Mostrando postagens com marcador GUI. Mostrar todas as postagens

terça-feira, 31 de outubro de 2017

Efeito gradiente - parte 2

Vamos aqui demonstrar o que muda na exibição quando são ajustadas determinadas propriedades como SmoothingMode e Pen.Width.

Tomamos como exemplo o mesmo código do post Desenhando linhas com efeito gradiente, invertendo as cores, passando azul para o centro e verde na extremidade e alterando as propriedades abaixo mencionadas.

Inicialmente, deixamos as coisas com os valores padrão.
$lgb = New-Object System.Drawing.Drawing2D.LinearGradientBrush`
($p1, $p2, $c1, $c2)
$pen = New-Object System.Drawing.Pen($lgb)
$pen.Width = 1
$g.SmoothingMode = [System.Drawing.Drawing2D.SmoothingMode]::Default

O resultado:

Mudando apenas $pen.Width=2

Alterando [System.Drawing.Drawing2D.SmoothingMode]::HighQuality, mas mantendo $pen.Width=1

Alterando [System.Drawing.Drawing2D.SmoothingMode]::HighQuality e $pen.Width=2

segunda-feira, 30 de outubro de 2017

Desenhando linhas com efeito gradiente

Aqui vamos demonstrar como explorar um efeito gradiente na composição da cor de uma linha.

Para tanto, precisamos dos seguintes componentes principais:
  • Definimos form.CreateGraphics
  • Definimos 2 pontos p1 e p2 para traçar a linha
  • Criamos o objeto LinearGradientBrush
  • Criamos o objeto pen
  • Traçamos a linha
[System.Drawing.Graphics]$g = $f.CreateGraphics()
$lgb = New-Object System.Drawing.Drawing2D.LinearGradientBrush($p1, $p2, $c1, $c2)
$pen = New-Object System.Drawing.Pen($lgb)
$g.DrawLine($pen, $p1, $p2)


Nesse exemplo de código, estaremos traçando linhas a partir de um ponto central a todos os 360º de um círculo. Cada linha terá o efeito gradiente com as cores verde e azul. O código é o seguinte:
[reflection.assembly]::LoadWithPartialName( "System.Windows.Forms")
[reflection.assembly]::LoadWithPartialName( "System.Drawing")
[System.Windows.Forms.Application]::EnableVisualStyles();

Function line([Int32]$val,[String]$c1,[String]$c2) {
    $ang = $val * ([math]::PI/180) ## em Radianos
    $r=150 ## tamanho da linha
    [System.Drawing.Graphics]$g = $f.CreateGraphics()   
    $p1 = New-Object System.Drawing.Point(190, 180)
    $p2 = New-Object System.Drawing.Point((190+$r*[math]::Cos($ang)), (180+$r*[math]::Sin($ang)))
    $lgb = New-Object System.Drawing.Drawing2D.LinearGradientBrush($p1, $p2, $c1, $c2)
    $pen = New-Object System.Drawing.Pen($lgb)
    $g.DrawLine($pen, $p1, $p2)
    $g.Dispose()
}

$f = New-Object Windows.Forms.Form
$f.Width = 400
$f.Height = 400
$f.Show()
$f.Refresh()

for ([Int32]$angulo=0;$angulo -lt 360;$angulo++) {
    line $angulo 'Green' 'Blue'
    Start-Sleep -Milliseconds 50
}

Start-Sleep -s 5
$f.Close()
$f.Dispose()

Segue o resultado:

sábado, 28 de outubro de 2017

Desenhando com Pixels - parte 2

Na parte 1 de Desenhando com Pixels, criou-se funções para o desenho de pontos, retas, triângulos e quadrados. Ainda, naquele código usou-se o artifício de carregar um bitmap de fundo.

Agora, vamos acrescentar novas funções, como o desenho de círculos, bem como o desenho de figuras geométricas com preenchimento. Para o desenho dessa característica, usaremos o que foi aprendido no post sobre recursividade, ou seja, o preenchimento de uma figura pode ser obtido através de chamadas recursivas à própria função de desenho.

Na plotagem, criamos um novo atributo "espessura", possibilitando a geração de pontos maiores e, como todas as demais figuras são baseadas em pontos, a consequente geração de retas, quadrados, triângulos e círculos mais espessos.

Outra melhoria foi a alteração no modo de compor o fundo de desenho, sem a necessidade da carga de um bitmap gerado externamente, seja de um arquivo ou de uma string base64. Agora, o fundo foi implementado assim:
$img = New-Object System.Drawing.Bitmap($form.Width, $form.Height)
$form.BackgroundImage = $img
$form.BackgroundImageLayout = "None"


A implementação completa é demonstrada abaixo:
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
##########################################################
Function plot([Int32]$x, [Int32] $y, [String] $cor, [Int32] $espessura) {
    for ([Int32]$ey=0;$ey -le $espessura;$ey++) {
        for ([Int32]$ex=0;$ex -le $espessura;$ex++) {
             $img.SetPixel($x+$ex, $y+$ey, $cor)
        }
    }
}
##########################################################
Function retaBresenham ([Int32]$x1, [Int32]$y1, [Int32]$x2, [Int32]$y2, [String]$cor, [Int32]$espessura) {
    [Int32] $dx = $x2 - $x1
    [Int32] $dy = $y2 - $y1
    [Int32] $stepx, $stepy

    if ($dy -lt 0) { 
        $dy = -$dy 
        $stepy = -1
    }
    else { $stepy = 1 }

    if ($dx -lt 0) { 
        $dx = -$dx 
        $stepx = -1
    }
    else { $stepx = 1 }

    $dy = $dy -shl 1
    $dx = $dx -shl 1

    plot $x1 $y1 $cor $espessura

    if ($dx -gt $dy) {
        [Int32] $fraction = $dy - ($dx -shr 1)
        while ($x1 -ne $x2) {
            if ($fraction -ge 0) {
                $y1 += $stepy
                $fraction -= $dx
            }
            $x1 += $stepx
            $fraction += $dy
            plot $x1 $y1 $cor $espessura
        }
    }
    else {
        [Int32] $fraction = $dx - ($dy -shr 1)
        while ($y1 -ne $y2) {
            if ($fraction -ge 0) {
                $x1 += $stepx
                $fraction -= $dy
            }
            $y1 += $stepy
            $fraction += $dx
            plot $x1 $y1 $cor $espessura
        }
    }
    
}

##########################################################
Function triangulo([Int32]$x1, [Int32]$y1, [Int32]$h, [String]$cor, [Int32]$espessura) {
    [Int32] $lado = ([math]::Sqrt(4*$h*$h/3))
    retaBresenham $x1 $y1 ($x1-($lado/2)) ($y1+$h) $cor $espessura
    retaBresenham $x1 $y1 ($x1+($lado/2)) ($y1+$h) $cor $espessura
    retaBresenham ($x1-($lado/2)) ($y1+$h) ($x1+($lado/2)) ($y1+$h) $cor $espessura
}

##########################################################
Function trianguloSolido([Int32]$x1, [Int32]$y1, [Int32]$h, [String]$cor) {
    ## Caso Base - Triângulo mínimo alcançado
    if ($h -lt 3) {
        triangulo $x1 $y1 $h $cor 2 
        return 
    }
    triangulo $x1 $y1 $h $cor 2
    return trianguloSolido $x1 ($y1+3) ($h-6) $cor
}

##########################################################
Function quadrado([Int32]$x1, [Int32]$y1, [Int32]$tam, [String]$cor, [Int32]$espessura) {
    retaBresenham $x1 $y1 ($x1+$tam) $y1 $cor $espessura
    retaBresenham $x1 $y1 $x1 ($y1+$tam) $cor $espessura
    retaBresenham $x1 ($y1+$tam) ($x1+$tam) ($y1+$tam) $cor $espessura
    retaBresenham ($x1+$tam) $y1 ($x1+$tam) ($y1+$tam) $cor $espessura
}

##########################################################
Function quadradoSolido([Int32]$x1, [Int32]$y1, [Int32]$tam, [String]$cor) {
    ## Caso Base - Quadrado mínimo alcançado
    if ($tam -lt 5) {
        quadrado $x1 $y1 $tam $cor 5
        return 
    }
    quadrado $x1 $y1 $tam $cor 5
    return quadradoSolido ($x1+5) ($y1+5) ($tam-10) $cor
}

##########################################################
Function circuloSolido([Int32]$xC, [Int32]$yC, [Int32]$r, [String]$cor) {
    ## Caso Base - Quadrado mínimo alcançado
    if ($r -lt 5) {
        plot $xC $yC $cor 5
        return
    }
    circulo $xC $yC $r $cor 5
    return circuloSolido $xC $yC ($r-5) $cor
}

##########################################################
Function circulo([Int32]$xC, [Int32]$yC, [Int32]$r, [String]$cor, [Int32]$espessura) {
    [Int32] $x = 0
    [Int32] $y = $r
    [Int32] $u = 1
    [Int32] $v = 2*$r-1
    [Int32] $E = 0

    while ($x -lt $y) {
        plot ($xC + $x) ($yC + $y) $cor $espessura ## NNE
        plot ($xC + $y) ($yC - $x) $cor $espessura ## ESE
        plot ($xC - $x) ($yC - $y) $cor $espessura ## SSW
        plot ($xC - $y) ($yC + $x) $cor $espessura ## WNW
        $x++
        $E += $u
        $u += 2
        if ($v -lt (2*$E)) {
            $y--
            $E -= $v
            $v -= 2
        }
        if ($x -gt $y) { return }
        plot ($xC + $y) ($yC + $x) $cor $espessura ## ENE
        plot ($xC + $x) ($yC - $y) $cor $espessura ## SSE
        plot ($xC - $y) ($yC - $x) $cor $espessura ## WSW
        plot ($xC - $x) ($yC + $y) $cor $espessura ## NNW
    }
}


Function bmpRefresh([System.Drawing.Bitmap]$img){
    $formGraphics.DrawImage($img,0,0,$img.Width,$img.Height)    
}

##########################################################
[Windows.Forms.Application]::EnableVisualStyles()
$form = New-Object Windows.Forms.Form
$form.Width = 600;
$form.Height = 480;
$img = New-Object System.Drawing.Bitmap($form.Width, $form.Height)
$form.BackgroundImage = $img
$form.BackgroundImageLayout = "None"
$formGraphics = $form.CreateGraphics()

$form.Add_Shown({

        ### Pontos
        for ([Int32]$x=30;$x -lt 55;$x+=5) {
            plot $x 50 'Red' 0
            plot $x 60 'Red' 1
            plot $x 70 'Red' 2
        }
        bmpRefresh($img)

        ### Reta
        retaBresenham 50 0 535 440 'Orange' 2
        retaBresenham 0 0 585 440 'Blue' 1
        bmpRefresh($img)

        ### Triângulo
        triangulo 100 100 100 'Green' 3
        triangulo 100 120 70 'Gray' 2
        bmpRefresh($img)

        ### Triângulo Sólido
        trianguloSolido 100 220 100 'Red'
        bmpRefresh($img)

        ### Quadrado
        quadrado 370 70 100 'Red' 5
        quadrado 390 90 60 'Black' 3
        quadrado 410 110 20 'blue' 2
        bmpRefresh($img)

        ### Quadrado Sólido
        quadradoSolido 250 70 100 'Green'
        bmpRefresh($img)

        ### Círculo
        circulo 200 380 40 'Black' 2
        bmpRefresh($img)

        circuloSolido 340 370 60 'Blue'
        bmpRefresh($img)
        
})

$form.ShowDialog()

O resultado:

quarta-feira, 25 de outubro de 2017

Desenhando com Pixels

Vamos usar o powershell para realizar algumas experiências com computação gráfica, tendo como premissa que um pixel (um ponto) pode ser considerado base para o desenho de outras estruturas como retas, triângulos, quadrados, etc.

Como nosso objetivo aqui é a implementação dessas estruturas básicas, vamos ignorar que o powershell já possui métodos implementados para desenhar retas, polígonos, etc.

  • Um pixel possui uma coordenada (x,y).
  • Uma reta será um conjunto de pontos; traçada através da implementação do algoritmo de Bresenham.
  • Implementaremos triângulos isósceles a partir de um ponto e a altura do triângulo fornecidos.
  • Quadrados serão implementados a partir de um ponto e o tamanho do lado fornecidos.

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

##########################################################
Function plot([Int32]$x, [Int32] $y, [String] $cor) {
    $img.SetPixel($x, $y, $cor) 
}

##########################################################
Function retaBresenham ([Int32]$x1, [Int32]$y1, [Int32]$x2, [Int32]$y2, [String] $cor) {
    [Int32] $dx = $x2 - $x1
    [Int32] $dy = $y2 - $y1
    [Int32] $stepx, $stepy

    if ($dy -lt 0) { 
        $dy = -$dy 
        $stepy = -1
    }
    else { $stepy = 1 }

    if ($dx -lt 0) { 
        $dx = -$dx 
        $stepx = -1
    }
    else { $stepx = 1 }

    $dy = $dy -shl 1
    $dx = $dx -shl 1

    plot $x1 $y1 $cor

    if ($dx -gt $dy) {
        [Int32] $fraction = $dy - ($dx -shr 1)
        while ($x1 -ne $x2) {
            if ($fraction -ge 0) {
                $y1 += $stepy
                $fraction -= $dx
            }
            $x1 += $stepx
            $fraction += $dy
            plot $x1 $y1 $cor
        }
    }
    else {
        [Int32] $fraction = $dx - ($dy -shr 1)
        while ($y1 -ne $y2) {
            if ($fraction -ge 0) {
                $x1 += $stepx
                $fraction -= $dy
            }
            $y1 += $stepy
            $fraction += $dx
            plot $x1 $y1 $cor
        }
    }
    
}

##########################################################
Function triangulo([Int32]$x1, [Int32]$y1, [Int32]$h, [String]$cor) {
    [Int32] $lado = ([math]::Sqrt(4*$h*$h/3))
    retaBresenham $x1 $y1 ($x1-($lado/2)) ($y1+$h) $cor
    retaBresenham $x1 $y1 ($x1+($lado/2)) ($y1+$h) $cor
    retaBresenham ($x1-($lado/2)) ($y1+$h) ($x1+($lado/2)) ($y1+$h) $cor
}

##########################################################
Function quadrado([Int32]$x1, [Int32]$y1, [Int32]$tam, [String]$cor) {
    retaBresenham $x1 $y1 ($x1+$tam) $y1 $cor
    retaBresenham $x1 $y1 $x1 ($y1+$tam) $cor
    retaBresenham $x1 ($y1+$tam) ($x1+$tam) ($y1+$tam) $cor
    retaBresenham ($x1+$tam) $y1 ($x1+$tam) ($y1+$tam) $cor
}

##########################################################
$B64 = "/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYEBAMFBwYHBwcGBwcICQsJCAgKCAcHCg0KCgsMDAwMBwkODw0MDgsMDAz/2wBDAQICAgMDAwYDAwYMCAcIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wAARCAHgAlgDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD9/KKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA//Z"
$imgBytes = [Convert]::FromBase64String($B64)
$imgStream = New-Object IO.MemoryStream($imgBytes, 0, $imgBytes.Length)
$img = [System.Drawing.Image]::FromStream($imgStream)
[Windows.Forms.Application]::EnableVisualStyles()
$form = New-Object Windows.Forms.Form
$form.Width = $img.Size.Width;
$form.Height = $img.Size.Height;
$pictureBox = new-object Windows.Forms.PictureBox
$pictureBox.Width =  $img.Size.Width;
$pictureBox.Height =  $img.Size.Height;

### Pontos
for ([Int32]$x=30;$x -lt 55;$x+=5) {
    plot $x 50 'Red'
    plot $x 60 'Red'
    plot $x 70 'Red'
}
### Reta
retaBresenham 0 0 585 440 'Blue'
retaBresenham 50 0 535 440 'Orange'
### Triângulo
triangulo 100 100 100 'Green'
triangulo 100 120 70 'Gray'
### Quadrado
quadrado 250 70 100 'Red'
quadrado 270 90 60 'Black'

$pictureBox.Image = $img;
$form.controls.add($pictureBox)
$form.Add_Shown( { $form.Activate() } )
$form.ShowDialog()

Neste exemplo, estamos criando alguns pontos, 2 retas, 2 triângulos e 2 quadrados.

quinta-feira, 7 de setembro de 2017

RSS no Out-GridView

RSS (Rich Site Summary) é um formato de distribuição de informações pela Internet. Através do recurso é possível obter notícias resumidas.

O objetivo aqui não é o de implementar um leitor completo, mas demonstrar que o Powershell tem bons recursos para a construção de leitor RSS. Com poucas linhas de código tem-se a possibilidade de acessar um feed de RSS publicado na Web, obter o XML correspondente e extrair as informações.

Extraídas as informações do XML, vamos guardá-las em um arquivo temporário. Esta etapa se faz necessária em função da codificação de caracteres. Para a correta exibição no Out-GridView faremos a codificação na hora de salvar para esse arquivo temporário, bem como ao carregarmos o conteúdo desse arquivo para o Out-GridView.

Estamos pegando como exemplo um RSS do G1, mas podia ser qualquer um. Para facilitar está sendo atribuído a uma variável $channelURI. O código está abaixo:
cls
$channelURI = "http://g1.globo.com/dynamo/tecnologia/rss2.xml"
$noticia = @()

$web = New-Object Net.WebClient
[xml]$resp = $web.DownloadString($channelURI) 
$noticia += $resp.rss.channel.title
$resp.rss.channel.item | ForEach { $noticia += $_.Title + ' - [' + $_.pubDate + ']' }

$noticia | Out-File $PSScriptRoot'\temp.txt' -Encoding default
Get-Content $PSScriptRoot'\temp.txt' -Encoding UTF8 | Out-GridView


Como resultado, temos o seguinte Out-GridView:

Out-GridView é um recurso bem interessante a ser utilizado em scripts. Por exemplo, tem um filtro integrado bem interessante. Nesse exemplo, se quisermos visualizar apenas as notícias do dia 06, basta digitarmos no filtro. O resultado é esse:

quarta-feira, 6 de setembro de 2017

Imagem de Fundo no Form

Explorando as Propriedades em instâncias da classe System.Windows.Forms.Form, vemos a possibilidade de definir uma imagem de fundo para o Form através de BackgroundImage.

Para atribuirmos a imagem a partir de um arquivo, podemos utilizar o método FromFile de System.Drawing.Image

GDI+ possui codificadores (encoders) e decodificadores (decoders) integrados, que suportam os seguintes formatos de imagem:
  • BMP
  • GIF
  • JPEG
  • PNG
  • TIFF

[void][System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[System.Windows.Forms.Application]::EnableVisualStyles() 

_Main  ### Chama a função _Main

Function _Main {
    $FormImg = New-Object System.Windows.Forms.Form 
    $FormImg.ClientSize = New-Object System.Drawing.Size(512,288) 
    $FormImg.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::Fixed3D
    $FormImg.Text = ".::. Inserindo uma imagem de fundo no Form .::."
    $FormImg.MaximizeBox = $false      #  - Desabilitar 'Maximizar' a Janela
    $FormImg.StartPosition = "CenterScreen"

    #######################
    ### Cria Imagem de Fundo a partir de um arquivo .JPG
    $FormImg.BackgroundImage = [System.Drawing.Image]::`
                            FromFile($PSScriptRoot + "\Img\Fundo.jpg")
    $FormImg.BackgroundImageLayout = "Stretch" ## ajusta-se ao tamanho do Form
                                     # None, Tile, Center, Stretch, Zoom

    #
    #$BotaoSair
    #
    $BotaoSair = New-Object System.Windows.Forms.Button
    $BotaoSair.Font = New-Object System.Drawing.Font("Microsoft Sans Serif", `
                                        10, [System.Drawing.FontStyle]::Bold)
    $BotaoSair.Text = "SAIR"

    ## Executa o código definido na variável $BotaoSair_Click
    $BotaoSair.Add_Click($BotaoSair_Click) 

    $FormImg.Controls.Add($BotaoSair)
    $BotaoSair.Size = New-Object System.Drawing.Size(80, 35)
    $BotaoSair_X = ($FormImg.ClientSize.Width / 2) - ($BotaoSair.Width / 2)
    $BotaoSair_Y = $FormImg.ClientSize.Height - 50
    $BotaoSair.Location = New-Object System.Drawing.`
                            Point($BotaoSair_X, $BotaoSair_Y)

    # Exibe o Form
    [System.Windows.Forms.Application]::Run($FormImg)

} ### End _Main

### Executado no evento de clique em $BotaoSair
$BotaoSair_Click = {
    $FormImg.Close()
}

O resultado da execução desse código é o seguinte:


No vídeo a seguir demonstra-se como codificar a imagem em Base64 e também como adicionar um ícone para o Form.

Códigos podem ser obtidos aqui.