Bild mit Powershell automatisch skalieren?
Hallo zusammen, ich möchte ein Bild automatisch mit PowerShell skalieren. Allerdings bekomm ich beim Ausführen der PowerShell einen Fehler und kann mir nicht erklären woher er kommt.
Bibliothek: ImageMagick – Convert, Edit, or Compose Digital Images
Skript:Bild Skalieren | German PowerSHELL
Fehlermeldung:
# Bibliothek importieren
Add-Type -Path "C:\Bibliothek\Libl"
$EingangOrdner = "C:\Script\ImageMagick\Input\BildSkalieren"
$AusgangOrdner = "C:\Script\ImageMagick\Output\BildSkalieren"
# Geometrie Objekt erstellen für die genaue Grösse
$Geometrie = [ImageMagick.MagickGeometry]::new(500,0) # Breite, Höhe
$Geometrie.IgnoreAspectRatio = $false # Seitenverhältnis beibehalten
# Alle Bilder aus EingangOrdner auslesen
$AlleBilder = Get-ChildItem $EingangOrdner -File
for($i = 0; $i -lt $AlleBilder.Count; $i ++)
{
$Bild = [ImageMagick.MagickImage]::new($AlleBilder[$i].FullName)
# Bild der festgelegten Geometrie anpassen
$Bild.Resize($Geometrie)
$Bild.Write("$AusgangOrdner\$($AlleBilder[$i].Name)")
}
2 Antworten
Ich habe keine Ahnung wo Du das Script aufgesammelt hast...
Ohne die Fehlermeldungen zu kennen kann ich nicht mal Ahnen wo der Fehler liegt.
Warum verwendest Du eine 3.Anbieter.dll? Windows hat alles Nötige gut dokumentiert an Bord. (und das Netz ist voll von Diversen C# und PowershellScripts zu diesem Thema)
ich setze noch eines hinzu:
#hier solltest Du nur rumfummeln, wenn Du weißt was Du tust...
function Resize-Image
{
<#
.EXAMPLE
Resize-Image -InputFile "C:\kitten.jpg" -OutputFile "C:\kitten2.jpg" -TargetSize 300 -Quality 100]
Resized die Größte Ausdehnung auf 300 , speichert mit 100% Jpeg-Qualität
#>
Param(
[Parameter(ValueFromPipeline=$true,Mandatory=$true)][string]$InputFile,
[Parameter(Mandatory=$true)][string]$OutputFile,
[Parameter(Mandatory=$true)][int][ValidateRange(1, [int]::MaxValue)]$TargetSize,
[parameter(Mandatory=$false)][int][ValidateRange(1, 100)]$Quality=80
)
Add-Type -AssemblyName System.Drawing
try{
$img = [System.Drawing.Image]::FromFile((Get-Item $InputFile))
}
catch{return} # habe keine Lust auf großartige Fehlerbehandlung, wenn die Quelldatei mal kein Bild ist... einfach wieder zurück zum Aufrufer
$ratioX = $TargetSize / $img.Width
$ratioY = $TargetSize / $img.Height
$ratio = $ratioY
if ($ratioX -le $ratioY) {
$ratio = $ratioX
}
[int32]$new_width = $img.Width * $ratio
[int32]$new_height = $img.Height * $ratio
$newImg = New-Object System.Drawing.Bitmap($new_width, $new_height)
# Zeichne Bild in ein leeres Canvas
$graph = [System.Drawing.Graphics]::FromImage($newImg)
$graph.InterpolationMode = 'HighQualityBicubic'
$graph.DrawImage($img, 0, 0, $new_width, $new_height)
#ermittle Codecinfomationen des Originalbildes und setze (Jpeg)Qualität ..für PNG etc. irrelevant
$Codec=[System.Drawing.Imaging.ImageCodecInfo]::GetImageEncoders()|?{$img.RawFormat -match $_.FormatID}
$encoderParams=New-Object System.Drawing.Imaging.EncoderParameters(1)
$encoderParams.Param[0]=New-Object System.Drawing.Imaging.EncoderParameter([System.Drawing.Imaging.Encoder]::Quality,$Quality)
$newImg.Save($OutputFile, $Codec, $encoderParams)
$graph.Dispose()
$img.Dispose()
$newImg.Dispose()
}
#=============== Hier gehts los =========================#
$ZielGroesse=500
$ZielQualitaet=70
$Zielordner=New-Item -Path "$Env:UserProfile\Desktop" -Name "ResizedImages" -ItemType "directory" -Force
# Auch wenn Resize-Image mit Dateien zurechtkommt welche keine Bilder sind, trotzdem auf gewünschte Formate filtern
Get-ChildItem -Path .\* -file -Include '*.jpg', '*.png', '*.gif'|
ForEach-Object{
$ZielDatei='{0}\{1}'-f $Zielordner.FullName,$_.Name
$QuellDatei=$_.FullName
Resize-Image -InputFile $QuellDatei -OutputFile $ZielDatei -TargetSize $ZielGroesse -Quality $ZielQualitaet
}
'Fretig'
pause1
habe die Antwort hoch genommen https://www.gutefrage.net/frage/bild-mit-powershell-automatisch-skalieren#answer-474035043
Ich habe die Antwort auf Deine Kommentar mal Hoch genommen:
Wo muss ich hier den Zielordner angeben.
Habe mal die Passage für die Angabe des ZielOrdners umgestaltet:
ab Zeile 113
...
#=============== Hier gehts los =========================#
#Hier den pfad für deinen Zielordner angeben
$Zielordner='c:\irgendwo\DeinOrdner'
...
Wie kann ich die Pixel Anzahl von 470x255 erreichen?
Das hatte ich im ersten Script garnicht erst erwogen, da es eigentlich bei vollautomatischen Sachen üblich ist das Seitenverhältnis des Originals zu übernehmen. Ich habe den Code entsprechen angepasst nun kannst Du Breite und Höhe in der Aufrufzeile des Cmdlet Resize-Image angeben:
Resize-Image -InputFile $QuellDatei -OutputFile $ZielDatei -Width 470 -Height 255
In der einfachsten Variante gibt's jedoch, je nach Vorlage, mehr oder wenige sichtbare hässliche Verzerrungen...
Um das zu vermeiden benötigen feste Bildgrößen eine Letterbox/Pillarbox in welcher das Bild im richtigen Seitenverhältnis dargestellt wird:
Resize-Image -InputFile $QuellDatei -OutputFile $ZielDatei -Width 470 -Height 255 -Quality 75 -KeepAspectRatio
und weil ich einmal am Basteln war kannst Du auch noch die Grundfarbe festlegen...
Resize-Image -InputFile $QuellDatei -OutputFile $ZielDatei -Width 470 -Height 255 -AR -BackgroundColor '#80ff40'
resize.ps1
function Resize-Image
{
<#
.PARAMETER -InputFile Type [string]
Original Datei voller Pfad nötig!
.PARAMETER -OutputFile Type [string]
Ausgabedatei
.PARAMETER -Width Type [int] >0 Alias -Size
Bildbreite bzw gröste Ausdehnung, wenn keine Breite angegeben
.PARAMETER -Height Type [int] >=0 optional
Wenn 0 oder nicht angegebe, wird auf größte Ausdenung vergrößert
.PARAMETER -Quality Type [int] 1..100 optional
Gibt für Jpeg aufgabe die Quallität an
.PARAMETER -KeepAspectRatio Switch optional Alias -AR
Wenn Höhe und Breite angegeben sind, wird unter Beibehaltung des Seitenvehältnisses in eine Letter-/PillarBox gezeichnet
.PARAMETER -BackgroundColor Type [string] optional Alias -BC
Gibt die Farbe für die Bildbox an (HTML-HexFormat #ffffff oder internationaler Farbname) https://en.wikipedia.org/wiki/Web_colors#Extended_colors
.EXAMPLE
-Resize die größte Ausdehnung auf 300 , speichert mit 100% Jpeg-Qualität
Resize-Image -InputFile "C:\kitten.jpg" -OutputFile "C:\kitten2.jpg" -Size 300 -Quality 100
-Resize auf 800x600 80% Jpeg-Qualität (Bild wird evtl. verzerrt)
Resize-Image -InputFile $QuellDatei -OutputFile $ZielDatei -Width 800 -Height 600
-dito ...Aspektratio erhalten, in Box zeichnen
Resize-Image -InputFile $QuellDatei -OutputFile $ZielDatei -Width 800 -Height 600 -Quality 75 -KeepAspectRatio
-dito mit farbiger Box (HTML-HexFormat #ffffff oder internationaler Farbname)
Resize-Image -InputFile $QuellDatei -OutputFile $ZielDatei -Width 300 -Height 800 -Quality 100 -AR -BackgroundColor '#80ff40'
#>
Param(
[Parameter(ValueFromPipeline=$true,Mandatory=$true)][string]$InputFile,
[Parameter(Mandatory=$true)][string]$OutputFile,
[Parameter(Mandatory=$true)][ValidateRange(1, [int]::MaxValue)]
[Alias('Size')][int]$Width,
[Parameter(Mandatory=$false)][int][ValidateRange(1, [int]::MaxValue)]$Height = 0,
[Parameter(Mandatory=$false)][int][ValidateRange(1, 100)]$Quality=80,
[Parameter(Mandatory=$false)][Alias('AR,KAR')][Switch]$KeepAspectRatio = $false,
[Parameter(Mandatory=$false)][Switch]$Crop = $false,
[Parameter(Mandatory=$false)][Alias('BC')][string]$BackgroundColor = '#000000'
)
Add-Type -AssemblyName System.Drawing
try{
$image = [System.Drawing.Image]::FromFile((Get-Item $InputFile))
}
catch{return} # habe keine Lust auf großartige Fehlerbehandlung, wenn die Quelldatei mal kein Bild ist... einfach wieder zurück zum Aufrufer
#Grundeinstellungen für die Zeichenfläche
$canvasDrawPosX = 0
$canvasDrawPosY = 0
$canvasWidth = $Width
$canvasHeight = $Height
if (!$Height){
$Height = $Width
# resize auf die größte Ausdehnung behalte Aspektratio
$ratioX = $Width / $image.Width
$ratioY = $Height / $image.Height
$ratio = [Math]::Min($ratioY,$ratioX) #Resize die gößere Ausdehnug ...Min() gibt die kleinere Ratio zurück
[int]$drawWidth = $image.Width * $ratio
[int]$drawHeight = $image.Height * $ratio
$canvasWidth = $drawWidth
$canvasHeight = $drawHeight
}
elseif ($KeepAspectRatio){
# zeichne in eine Box
$ratioX = $canvasWidth / $image.Width
$ratioY = $canvasHeight / $image.Height
$ratio = [Math]::Min($ratioY,$ratioX)
$drawWidth = [Math]::Ceiling($image.Width * $ratio)
$drawHeight = [Math]::Ceiling($image.Height * $ratio)
#Zeichenpositionen berechnen
if ($ratioY -lt $ratioX){
$canvasDrawPosX = [Math]::Floor(($canvasWidth - $drawWidth) / 2) # für Pilarbox
}
else{
$canvasDrawPosY= [Math]::Floor(($canvasHeight - $drawHeight) / 2) # für Letterbox
}
}
else{
#egal... dann kanns eben verzerrt werden
$drawWidth = $canvasWidth
$drawHeight = $canvasHeight
}
#erzeuge Zeichenfläche
$canvas = New-Object System.Drawing.Bitmap($canvasWidth, $canvasHeight)
$graph = [System.Drawing.Graphics]::FromImage($canvas)
$graph.InterpolationMode = 'HighQualityBicubic'
try{ $graph.Clear($BackgroundColor) }catch{} #fehlerhafte Farbangabe abfangen (bei Fehler bleibts Schwarz)
# Zeichne Bild in ein leeres Canvas
$graph.DrawImage($image, $canvasDrawPosX , $canvasDrawPosY, $drawWidth, $drawHeight)
#ermittle Codecinfomationen des Originalbildes und setze (Jpeg)Qualität ..für PNG etc. irrelevant
$Codec=[System.Drawing.Imaging.ImageCodecInfo]::GetImageEncoders()|?{$image.RawFormat -match $_.FormatID}
$encoderParams=New-Object System.Drawing.Imaging.EncoderParameters(1)
$encoderParams.Param[0]=New-Object System.Drawing.Imaging.EncoderParameter([System.Drawing.Imaging.Encoder]::Quality,$Quality)
$canvas.Save($OutputFile, $Codec, $encoderParams)
$graph.Dispose()
$image.Dispose()
$canvas.Dispose()
}
#=============== Hier gehts los =========================#
#Hier den pfad für deinen Zielordner angeben
$Zielordner='c:\irgendwo\DeinOrdner'
$Zielordner=New-Item -Path $Zielordner -ItemType "directory" -Force
# Auch wenn Resize-Image mit Dateien zurechtkommt welche keine Bilder sind, trotzdem auf gewünschte Formate filtern
Get-ChildItem -Path .\* -file -Include '*.jpg', '*.png', '*.gif'|
ForEach-Object{
$ZielDatei='{0}\{1}'-f $Zielordner.FullName,$_.Name
$QuellDatei=$_.FullName
#hier mal ein Paar vorgefertigte Aufruf-Beispiele zum Exprimentieren.
#Einfach vor der gewünschten Zeile das Kommentarzeichen # entfernen setzen:
#Resize-Image -InputFile $QuellDatei -OutputFile $ZielDatei -Size 470 -Quality 100
#Resize-Image -InputFile $QuellDatei -OutputFile $ZielDatei -Width 470 -Height 255 -Quality 75 -KeepAspectRatio
#Resize-Image -InputFile $QuellDatei -OutputFile $ZielDatei -Width 470 -Height 255 -Quality 100 -AR -BackgroundColor 'MidnightBlue'
Resize-Image -InputFile $QuellDatei -OutputFile $ZielDatei -Width 470 -Height 255 -AR -BackgroundColor '#80ff40'
#Resize-Image -InputFile $QuellDatei -OutputFile $ZielDatei -Width 470 -Height 255
}
'Fertig'
pause
Ich habe Dir zum experimentieren einige Aufrufzeilen vorbereitet.
Ab der mit :
#=============== Hier gehts los =========================#
... gekennzeichneten Stelle kannst Du nach Herzenslust herumspielen ohne besonders viel kaputt zu machen
hier noch eine Farbtabelle mit den internationalen Farbnamen






Hallo Erzesel, ich möchte alle Bilder in einer Datei auf die Größe 470x255 skalieren. Cool das Windows, das auch kann. Ich bin bei meinen Recherchen auf einen Youtube-Kanal mit dem Namen german Powershell aufmerksam geworden. Bei ihm, dass das Skript von mir ohne Probleme funktioniert. Allerdings ist es sehr cool, dass ohne eine 3 Hersteller .dll funktioniert.
Ich hätte allerdings noch 2 Fragen.
Wo muss ich hier den Zielordner angeben.
Wie kann ich die Pixel Anzahl von 470x255 erreichen?
Vielen Dank schon mal im Voraus.