Eis o código melhorado.
Function FloydSteinberg([System.Drawing.Image]$Img) { Write-Host -ForegroundColor Green "Aplicando efeito FloydSteinberg na imagem..." Write-Host -ForegroundColor Green "Será salvo na mesma pasta um arquivo NomeOriginal_FloydSteinberg.jpg" ## Primeiro converte a imagem para tons de cinza Write-Host "Convertendo para tons de cinza e calculando min/max de B/W" [Int32]$BLACK = 255 [Int32]$WHITE = 0 Foreach($y in (0..($Img.Height-1))) { Foreach($x in (0..($Img.Width-1))) { $ColorPixel = $Img.GetPixel($x,$y) $R = (0.2125*$ColorPixel.R)+(0.7154*$ColorPixel.G)+(0.0721*$ColorPixel.B) $G = $R $B = $R $A = $ColorPixel.A $Img.SetPixel($x,$y,[System.Drawing.Color]::FromArgb([Int32]$A,[Int32]$R,[Int32]$G,[Int32]$B)) If ($R -lt $BLACK) { $BLACK = $R} If ($R -gt $WHITE) { $WHITE = $R} } } Write-Host "WHITE:$WHITE" Write-Host "BLACK:$BLACK" [Int32]$T = ($BLACK + $WHITE) / 2 Write-Host "Aplicando Efeito FloydSteinberg..." [Int32]$p=0 [Int32]$Err Foreach($y in (0..($Img.Height-1))) { $p++ If ($p -gt (($Img.Height)*0.05)) { Write-Host -NoNewLine '.' $p = 0 } Foreach($x in (0..($Img.Width-1))) { $ColorPixel = $Img.GetPixel($x,$y) ## FloydSteinberg If ($ColorPixel.R -lt $T) { $R = $BLACK $G = $BLACK $B = $BLACK $Err = $ColorPixel.R - $BLACK } Else { $R = $WHITE $G = $WHITE $B = $WHITE $Err = $ColorPixel.R - $WHITE } ## SetPixel para efeito FloydSteinberg $A = $ColorPixel.A $Img.SetPixel($x,$y,[System.Drawing.Color]::FromArgb([Int32]$A,[Int32]$R,[Int32]$G,[Int32]$B)) If (($x+1) -lt ($Img.Width-1)) { $CPx1 = $Img.GetPixel(($x+1),$y) $Ax1 = $CPx1.A $Rx1 = $CPx1.R + 3 * $Err / 8 $Gx1 = $CPx1.G + 3 * $Err / 8 $Bx1 = $CPx1.B + 3 * $Err / 8 If ($Rx1 -lt 0) { $Rx1 = 0} If ($Gx1 -lt 0) { $Gx1 = 0} If ($Bx1 -lt 0) { $Bx1 = 0} If ($Rx1 -gt 255) { $Rx1 = 255} If ($Gx1 -gt 255) { $Gx1 = 255} If ($Bx1 -gt 255) { $Bx1 = 255} $Img.SetPixel(($x+1),$y,[System.Drawing.Color]::FromArgb([Int32]$Ax1,[Int32]$Rx1,[Int32]$Gx1,[Int32]$Bx1)) } If (($y+1) -lt ($Img.Height-1)) { $CPy1 = $Img.GetPixel($x,($y+1)) $Ay1 = $CPy1.A $Ry1 = $CPy1.R + 3 * $Err / 8 $Gy1 = $CPy1.G + 3 * $Err / 8 $By1 = $CPy1.B + 3 * $Err / 8 If ($Ry1 -lt 0) { $Ry1 = 0} If ($Gy1 -lt 0) { $Gy1 = 0} If ($By1 -lt 0) { $By1 = 0} If ($Ry1 -gt 255) { $Ry1 = 255} If ($Gy1 -gt 255) { $Gy1 = 255} If ($By1 -gt 255) { $By1 = 255} $Img.SetPixel($x,($y+1),[System.Drawing.Color]::FromArgb([Int32]$Ay1,[Int32]$Ry1,[Int32]$Gy1,[Int32]$By1)) } If ((($y+1) -lt ($Img.Height-1)) -And (($x+1) -lt ($Img.Width-1))) { $CPx1y1 = $Img.GetPixel(($x+1),($y+1)) $Ax1y1 = $CPx1y1.A $Rx1y1 = $CPx1y1.R + $Err / 4 $Gx1y1 = $CPx1y1.G + $Err / 4 $Bx1y1 = $CPx1y1.B + $Err / 4 If ($Rx1y1 -lt 0) { $Rx1y1 = 0} If ($Gx1y1 -lt 0) { $Gx1y1 = 0} If ($Bx1y1 -lt 0) { $Bx1y1 = 0} If ($Rx1y1 -gt 255) { $Rx1y1 = 255} If ($Gx1y1 -gt 255) { $Gx1y1 = 255} If ($Bx1y1 -gt 255) { $Bx1y1 = 255} $Img.SetPixel(($x+1),($y+1),[System.Drawing.Color]::FromArgb([Int32]$Ax1y1,[Int32]$Rx1y1,[Int32]$Gx1y1,[Int32]$Bx1y1)) } } ## ForEach $x } ## ForEach $y } ## EndFunction FloydSteinberg $Arquivo = New-Object System.Windows.Forms.OpenFileDialog $Arquivo.filter = "Imagens (*.PNG;*.BMP;*.JPG;*.JPEG;*.GIF)|*.PNG;*.BMP;*.JPG;*.JPEG;*.GIF" $Arquivo.ShowDialog() | Out-Null $ArquivoSemExt = ($Arquivo.filename).Substring(0,($Arquivo.filename).Length-4) $Img = [System.Drawing.Image]::FromFile($Arquivo.filename) Clear-Host Write-Host "##############################################" Write-Host "Arquivo de Imagem:"$Arquivo.filename Write-Host "##############################################" FloydSteinberg $Img Write-Host "" Write-Host -ForegroundColor Yellow "Conversão concluída!" $Img.Save($ArquivoSemExt+"_FloydSteinberg.jpg","JPEG") $Img.Dispose()
Floyd-Steinberg Verdadeiro
Function FloydSteinberg([System.Drawing.Image]$Img) { Write-Host -ForegroundColor Green "Aplicando efeito FloydSteinberg na imagem..." Write-Host -ForegroundColor Green "Será salvo na mesma pasta um arquivo NomeOriginal_FloydSteinberg.jpg" ## Primeiro converte a imagem para tons de cinza Write-Host "Convertendo para tons de cinza e calculando min/max de B/W" [Int32]$BLACK = 255 [Int32]$WHITE = 0 Foreach($y in (0..($Img.Height-1))) { Foreach($x in (0..($Img.Width-1))) { $ColorPixel = $Img.GetPixel($x,$y) $R = (0.2125*$ColorPixel.R)+(0.7154*$ColorPixel.G)+(0.0721*$ColorPixel.B) $G = $R $B = $R $A = $ColorPixel.A $Img.SetPixel($x,$y,[System.Drawing.Color]::FromArgb([Int32]$A,[Int32]$R,[Int32]$G,[Int32]$B)) If ($ColorPixel.R -lt $BLACK) { $BLACK = $ColorPixel.R} If ($ColorPixel.R -gt $WHITE) { $WHITE = $ColorPixel.R} } } Write-Host "WHITE:$WHITE" Write-Host "BLACK:$BLACK" [Int32]$T = ($BLACK + $WHITE) / 2 Write-Host "Aplicando Efeito FloydSteinberg..." [Int32]$p=0 [Int32]$quant_error=0 Foreach($y in (0..($Img.Height-1))) { $p++ If ($p -gt (($Img.Height)*0.05)) { Write-Host -NoNewLine '.' $p = 0 } Foreach($x in (0..($Img.Width-1))) { $ColorPixel = $Img.GetPixel($x,$y) ## FloydSteinberg If ($ColorPixel.R -lt $T) { $R = $BLACK $G = $BLACK $B = $BLACK $quant_error = $ColorPixel.R - $BLACK } Else { $R = $WHITE $G = $WHITE $B = $WHITE $quant_error = $ColorPixel.R - $WHITE } $A = $ColorPixel.A $Img.SetPixel($x,$y,[System.Drawing.Color]::FromArgb([Int32]$A,[Int32]$R,[Int32]$G,[Int32]$B)) ## SetPixels FloydSteinberg (x+1,y) If (($x+1) -lt ($Img.Width-1)) { $CPx1 = $Img.GetPixel(($x+1),$y) $Ax1 = $CPx1.A $Rx1 = $CPx1.R + $quant_error * 7 / 16 $Gx1 = $CPx1.G + $quant_error * 7 / 16 $Bx1 = $CPx1.B + $quant_error * 7 / 16 If ($Rx1 -lt 0) { $Rx1 = 0} If ($Gx1 -lt 0) { $Gx1 = 0} If ($Bx1 -lt 0) { $Bx1 = 0} If ($Rx1 -gt 255) { $Rx1 = 255} If ($Gx1 -gt 255) { $Gx1 = 255} If ($Bx1 -gt 255) { $Bx1 = 255} $Img.SetPixel(($x+1),$y,[System.Drawing.Color]::FromArgb([Int32]$Ax1,[Int32]$Rx1,[Int32]$Gx1,[Int32]$Bx1)) } ## SetPixels FloydSteinberg (x-1,y+1) If ( (($y+1) -lt ($Img.Height-1)) -And (($x-1) -gt 0) ) { $CPx1y1 = $Img.GetPixel(($x-1),($y+1)) $Ax1y1 = $CPx1y1.A $Rx1y1 = $CPx1y1.R + $quant_error * 3 / 16 $Gx1y1 = $CPx1y1.G + $quant_error * 3 / 16 $Bx1y1 = $CPx1y1.B + $quant_error * 3 / 16 If ($Rx1y1 -lt 0) { $Rx1y1 = 0} If ($Gx1y1 -lt 0) { $Gx1y1 = 0} If ($Bx1y1 -lt 0) { $Bx1y1 = 0} If ($Rx1y1 -gt 255) { $Rx1y1 = 255} If ($Gx1y1 -gt 255) { $Gx1y1 = 255} If ($Bx1y1 -gt 255) { $Bx1y1 = 255} $Img.SetPixel(($x-1),($y+1),[System.Drawing.Color]::FromArgb([Int32]$Ax1y1,[Int32]$Rx1y1,[Int32]$Gx1y1,[Int32]$Bx1y1)) } ## SetPixels FloydSteinberg (x,y+1) If (($y+1) -lt ($Img.Height-1)) { $CPy1 = $Img.GetPixel($x,($y+1)) $Ay1 = $CPy1.A $Ry1 = $CPy1.R + $quant_error * 5 / 16 $Gy1 = $CPy1.G + $quant_error * 5 / 16 $By1 = $CPy1.B + $quant_error * 5 / 16 If ($Ry1 -lt 0) { $Ry1 = 0} If ($Gy1 -lt 0) { $Gy1 = 0} If ($By1 -lt 0) { $By1 = 0} If ($Ry1 -gt 255) { $Ry1 = 255} If ($Gy1 -gt 255) { $Gy1 = 255} If ($By1 -gt 255) { $By1 = 255} $Img.SetPixel($x,($y+1),[System.Drawing.Color]::FromArgb([Int32]$Ay1,[Int32]$Ry1,[Int32]$Gy1,[Int32]$By1)) } ## SetPixels FloydSteinberg (x+1,y+1) If ((($y+1) -lt ($Img.Height-1)) -And (($x+1) -lt ($Img.Width-1))) { $CPx1y1 = $Img.GetPixel(($x+1),($y+1)) $Ax1y1 = $CPx1y1.A $Rx1y1 = $CPx1y1.R + $quant_error * 1 / 16 $Gx1y1 = $CPx1y1.G + $quant_error * 1 / 16 $Bx1y1 = $CPx1y1.B + $quant_error * 1 / 16 If ($Rx1y1 -lt 0) { $Rx1y1 = 0} If ($Gx1y1 -lt 0) { $Gx1y1 = 0} If ($Bx1y1 -lt 0) { $Bx1y1 = 0} If ($Rx1y1 -gt 255) { $Rx1y1 = 255} If ($Gx1y1 -gt 255) { $Gx1y1 = 255} If ($Bx1y1 -gt 255) { $Bx1y1 = 255} $Img.SetPixel(($x+1),($y+1),[System.Drawing.Color]::FromArgb([Int32]$Ax1y1,[Int32]$Rx1y1,[Int32]$Gx1y1,[Int32]$Bx1y1)) } } ## ForEach $x } ## ForEach $y } ## EndFunction FloydSteinberg $Arquivo = New-Object System.Windows.Forms.OpenFileDialog $Arquivo.filter = "Imagens (*.PNG;*.BMP;*.JPG;*.JPEG;*.GIF)|*.PNG;*.BMP;*.JPG;*.JPEG;*.GIF" $Arquivo.ShowDialog() | Out-Null $ArquivoSemExt = ($Arquivo.filename).Substring(0,($Arquivo.filename).Length-4) $Img = [System.Drawing.Image]::FromFile($Arquivo.filename) Clear-Host Write-Host "##############################################" Write-Host "Arquivo de Imagem:"$Arquivo.filename Write-Host "##############################################" FloydSteinberg $Img Write-Host "" Write-Host -ForegroundColor Yellow "Conversão concluída!" $Img.Save($ArquivoSemExt+"_FloydSteinberg.jpg","JPEG") $Img.Dispose()
Abaixo comparativo entre o falso e o verdadeiro Floyd-Steinberg
Nenhum comentário:
Postar um comentário