@@ -14,100 +14,171 @@ function Add-Log {
1414
1515# ---------- main form ----------
1616$form = New-Object System.Windows.Forms.Form
17- $form.Text = " Image Converter ( PNG/JPG/AVIF -> WebP / AVIF) "
17+ $form.Text = " PNG/JPG/AVIF -> WebP / AVIF Converter "
1818$form.StartPosition = " CenterScreen"
19- $form.Size = New-Object System.Drawing.Size(700 , 520 )
19+ $form.Size = New-Object System.Drawing.Size(780 , 580 )
2020$form.FormBorderStyle = ' FixedDialog'
2121$form.MaximizeBox = $false
22+ $form.AllowDrop = $true
23+ $form.Font = New-Object System.Drawing.Font(" Segoe UI" , 9 )
24+
25+ # ---------- title ----------
26+ $labelTitle = New-Object System.Windows.Forms.Label
27+ $labelTitle.Text = " Image Converter for Web (PNG/JPG/AVIF -> WebP / AVIF)"
28+ $labelTitle.Location = New-Object System.Drawing.Point(15 , 10 )
29+ $labelTitle.AutoSize = $true
30+ $labelTitle.Font = New-Object System.Drawing.Font(" Segoe UI Semibold" , 11 )
31+ $form.Controls.Add ($labelTitle )
32+
33+ $labelSubtitle = New-Object System.Windows.Forms.Label
34+ $labelSubtitle.Text = " Select a folder with images, set quality and output format, then click Start."
35+ $labelSubtitle.Location = New-Object System.Drawing.Point(15 , 35 )
36+ $labelSubtitle.AutoSize = $true
37+ $labelSubtitle.ForeColor = [System.Drawing.Color ]::Gray
38+ $form.Controls.Add ($labelSubtitle )
2239
2340# ---------- folder selection ----------
24- $labelFolder = New-Object System.Windows.Forms.Label
25- $labelFolder.Text = " Folder:"
26- $labelFolder.Location = New-Object System.Drawing.Point(15 , 20 )
27- $labelFolder.AutoSize = $true
28- $form.Controls.Add ($labelFolder )
29-
30- $textFolder = New-Object System.Windows.Forms.TextBox
31- $textFolder.Location = New-Object System.Drawing.Point(80 , 15 )
32- $textFolder.Size = New-Object System.Drawing.Size(480 , 25 )
33- $form.Controls.Add ($textFolder )
34-
35- $buttonBrowse = New-Object System.Windows.Forms.Button
36- $buttonBrowse.Text = " Browse..."
37- $buttonBrowse.Location = New-Object System.Drawing.Point(570 , 13 )
38- $buttonBrowse.Size = New-Object System.Drawing.Size(90 , 28 )
39- $form.Controls.Add ($buttonBrowse )
40-
41- $folderDialog = New-Object System.Windows.Forms.FolderBrowserDialog
41+ $groupFolder = New-Object System.Windows.Forms.GroupBox
42+ $groupFolder.Text = " Source folder "
43+ $groupFolder.Location = New-Object System.Drawing.Point(15 , 65 )
44+ $groupFolder.Size = New-Object System.Drawing.Size(740 , 80 )
45+ $form.Controls.Add ($groupFolder )
46+
47+ $labelFolder = New-Object System.Windows.Forms.Label
48+ $labelFolder.Text = " Folder:"
49+ $labelFolder.Location = New-Object System.Drawing.Point(10 , 30 )
50+ $labelFolder.AutoSize = $true
51+ $groupFolder.Controls.Add ($labelFolder )
52+
53+ $textFolder = New-Object System.Windows.Forms.TextBox
54+ $textFolder.Location = New-Object System.Drawing.Point(70 , 27 )
55+ $textFolder.Size = New-Object System.Drawing.Size(540 , 24 )
56+ $textFolder.AllowDrop = $true
57+ $groupFolder.Controls.Add ($textFolder )
58+
59+ $buttonBrowse = New-Object System.Windows.Forms.Button
60+ $buttonBrowse.Text = " Browse..."
61+ $buttonBrowse.Location = New-Object System.Drawing.Point(620 , 25 )
62+ $buttonBrowse.Size = New-Object System.Drawing.Size(90 , 28 )
63+ $groupFolder.Controls.Add ($buttonBrowse )
64+
65+ $folderDialog = New-Object System.Windows.Forms.FolderBrowserDialog
4266
4367$buttonBrowse.Add_Click ({
4468 if ($folderDialog.ShowDialog () -eq " OK" ) {
4569 $textFolder.Text = $folderDialog.SelectedPath
4670 }
4771})
4872
49- # ---------- quality ----------
50- $labelQuality = New-Object System.Windows.Forms.Label
51- $labelQuality.Text = " Quality (0-100):"
52- $labelQuality.Location = New-Object System.Drawing.Point(15 , 55 )
53- $labelQuality.AutoSize = $true
54- $form.Controls.Add ($labelQuality )
55-
56- $textQuality = New-Object System.Windows.Forms.TextBox
57- $textQuality.Location = New-Object System.Drawing.Point(120 , 52 )
58- $textQuality.Size = New-Object System.Drawing.Size(50 , 25 )
59- $textQuality.Text = " 85"
60- $form.Controls.Add ($textQuality )
61-
62- # ---------- output format ----------
63- $labelFormat = New-Object System.Windows.Forms.Label
64- $labelFormat.Text = " Output format:"
65- $labelFormat.Location = New-Object System.Drawing.Point(200 , 55 )
66- $labelFormat.AutoSize = $true
67- $form.Controls.Add ($labelFormat )
68-
69- $comboFormat = New-Object System.Windows.Forms.ComboBox
70- $comboFormat.Location = New-Object System.Drawing.Point(290 , 52 )
71- $comboFormat.Size = New-Object System.Drawing.Size(80 , 25 )
72- $comboFormat.DropDownStyle = ' DropDownList'
73+ # Drag & Drop to folder textbox
74+ $textFolder.Add_DragEnter ({
75+ if ($_.Data.GetDataPresent ([Windows.Forms.DataFormats ]::FileDrop)) {
76+ $_.Effect = ' Copy'
77+ } else {
78+ $_.Effect = ' None'
79+ }
80+ })
81+
82+ $textFolder.Add_DragDrop ({
83+ $paths = $_.Data.GetData ([Windows.Forms.DataFormats ]::FileDrop)
84+ if ($paths -and $paths.Length -gt 0 ) {
85+ $first = $paths [0 ]
86+ if (Test-Path $first - PathType Container) {
87+ $textFolder.Text = $first
88+ } else {
89+ $textFolder.Text = [System.IO.Path ]::GetDirectoryName($first )
90+ }
91+ }
92+ })
93+
94+ # ---------- settings ----------
95+ $groupSettings = New-Object System.Windows.Forms.GroupBox
96+ $groupSettings.Text = " Settings "
97+ $groupSettings.Location = New-Object System.Drawing.Point(15 , 155 )
98+ $groupSettings.Size = New-Object System.Drawing.Size(740 , 110 )
99+ $form.Controls.Add ($groupSettings )
100+
101+ # Quality
102+ $labelQuality = New-Object System.Windows.Forms.Label
103+ $labelQuality.Text = " Quality (0-100):"
104+ $labelQuality.Location = New-Object System.Drawing.Point(10 , 30 )
105+ $labelQuality.AutoSize = $true
106+ $groupSettings.Controls.Add ($labelQuality )
107+
108+ $textQuality = New-Object System.Windows.Forms.TextBox
109+ $textQuality.Location = New-Object System.Drawing.Point(120 , 27 )
110+ $textQuality.Size = New-Object System.Drawing.Size(50 , 24 )
111+ $textQuality.Text = " 85"
112+ $groupSettings.Controls.Add ($textQuality )
113+
114+ $labelQualityHint = New-Object System.Windows.Forms.Label
115+ $labelQualityHint.Text = " (85 is a good default for web)"
116+ $labelQualityHint.Location = New-Object System.Drawing.Point(180 , 30 )
117+ $labelQualityHint.AutoSize = $true
118+ $labelQualityHint.ForeColor = [System.Drawing.Color ]::Gray
119+ $groupSettings.Controls.Add ($labelQualityHint )
120+
121+ # Output format
122+ $labelFormat = New-Object System.Windows.Forms.Label
123+ $labelFormat.Text = " Output format:"
124+ $labelFormat.Location = New-Object System.Drawing.Point(10 , 65 )
125+ $labelFormat.AutoSize = $true
126+ $groupSettings.Controls.Add ($labelFormat )
127+
128+ $comboFormat = New-Object System.Windows.Forms.ComboBox
129+ $comboFormat.Location = New-Object System.Drawing.Point(120 , 62 )
130+ $comboFormat.Size = New-Object System.Drawing.Size(100 , 24 )
131+ $comboFormat.DropDownStyle = ' DropDownList'
73132[void ]$comboFormat.Items.Add (" webp" )
74133[void ]$comboFormat.Items.Add (" avif" )
75- $comboFormat.SelectedIndex = 0
76- $form.Controls.Add ($comboFormat )
77-
78- # ---------- checkboxes ----------
79- $checkDelete = New-Object System.Windows.Forms.CheckBox
80- $checkDelete.Text = " Delete original source files after conversion"
81- $checkDelete.Location = New-Object System.Drawing.Point(15 , 85 )
82- $checkDelete.AutoSize = $true
83- $checkDelete.Checked = $true
84- $form.Controls.Add ($checkDelete )
85-
86- $checkRecursive = New-Object System.Windows.Forms.CheckBox
87- $checkRecursive.Text = " Include subfolders (recursive)"
88- $checkRecursive.Location = New-Object System.Drawing.Point(15 , 110 )
89- $checkRecursive.AutoSize = $true
90- $checkRecursive.Checked = $false
91- $form.Controls.Add ($checkRecursive )
134+ $comboFormat.SelectedIndex = 0
135+ $groupSettings.Controls.Add ($comboFormat )
136+
137+ # ---------- options ----------
138+ $groupOptions = New-Object System.Windows.Forms.GroupBox
139+ $groupOptions.Text = " Options "
140+ $groupOptions.Location = New-Object System.Drawing.Point(15 , 275 )
141+ $groupOptions.Size = New-Object System.Drawing.Size(740 , 90 )
142+ $form.Controls.Add ($groupOptions )
143+
144+ $checkDelete = New-Object System.Windows.Forms.CheckBox
145+ $checkDelete.Text = " Delete original source files after successful conversion"
146+ $checkDelete.Location = New-Object System.Drawing.Point(10 , 25 )
147+ $checkDelete.AutoSize = $true
148+ $checkDelete.Checked = $true
149+ $groupOptions.Controls.Add ($checkDelete )
150+
151+ $checkRecursive = New-Object System.Windows.Forms.CheckBox
152+ $checkRecursive.Text = " Include subfolders (recursive)"
153+ $checkRecursive.Location = New-Object System.Drawing.Point(10 , 50 )
154+ $checkRecursive.AutoSize = $true
155+ $groupOptions.Controls.Add ($checkRecursive )
92156
93157# ---------- start button ----------
94- $buttonStart = New-Object System.Windows.Forms.Button
95- $buttonStart.Text = " Start conversion"
96- $buttonStart.Location = New-Object System.Drawing.Point(15 , 140 )
97- $buttonStart.Size = New-Object System.Drawing.Size(150 , 35 )
158+ $buttonStart = New-Object System.Windows.Forms.Button
159+ $buttonStart.Text = " Start conversion"
160+ $buttonStart.Location = New-Object System.Drawing.Point(15 , 380 )
161+ $buttonStart.Size = New-Object System.Drawing.Size(160 , 36 )
162+ $buttonStart.Font = New-Object System.Drawing.Font(" Segoe UI Semibold" , 9 )
98163$form.Controls.Add ($buttonStart )
99164
100- # ---------- log textbox ----------
101- $logBox = New-Object System.Windows.Forms.TextBox
102- $logBox.Location = New-Object System.Drawing.Point(15 , 190 )
103- $logBox.Size = New-Object System.Drawing.Size(645 , 270 )
104- $logBox.Multiline = $true
105- $logBox.ScrollBars = " Vertical"
106- $logBox.ReadOnly = $true
107- $logBox.Font = New-Object System.Drawing.Font(" Consolas" , 9 )
165+ # ---------- log output ----------
166+ $labelLog = New-Object System.Windows.Forms.Label
167+ $labelLog.Text = " Log output:"
168+ $labelLog.Location = New-Object System.Drawing.Point(15 , 425 )
169+ $labelLog.AutoSize = $true
170+ $form.Controls.Add ($labelLog )
171+
172+ $logBox = New-Object System.Windows.Forms.TextBox
173+ $logBox.Location = New-Object System.Drawing.Point(15 , 445 )
174+ $logBox.Size = New-Object System.Drawing.Size(740 , 90 )
175+ $logBox.Multiline = $true
176+ $logBox.ScrollBars = " Vertical"
177+ $logBox.ReadOnly = $true
178+ $logBox.Font = New-Object System.Drawing.Font(" Consolas" , 9 )
108179$form.Controls.Add ($logBox )
109180
110- # ---------- start button logic ----------
181+ # ---------- start logic ----------
111182$buttonStart.Add_Click ({
112183 $folder = $textFolder.Text.Trim ()
113184 if ([string ]::IsNullOrWhiteSpace($folder ) -or -not (Test-Path $folder )) {
@@ -119,95 +190,82 @@ $buttonStart.Add_Click({
119190 $magickCmd = Get-Command magick - ErrorAction SilentlyContinue
120191 if (-not $magickCmd ) {
121192 [System.Windows.Forms.MessageBox ]::Show(
122- " ImageMagick 'magick' command not found in PATH .`r`n Please install ImageMagick." ,
193+ " ImageMagick 'magick' command not found.`r`n Please install ImageMagick." ,
123194 " ImageMagick not found" ,
124195 " OK" ,
125196 " Error"
126197 )
127198 return
128199 }
129200
130- # -------- FIXED QUALITY VALIDATION --------
201+ # Quality validation
131202 $qualityText = $textQuality.Text.Trim ()
132-
133203 [int ]$quality = 0
204+
134205 if (-not [int ]::TryParse($qualityText , [ref ]$quality )) {
135- [System.Windows.Forms.MessageBox ]::Show(
136- " Quality must be an integer between 0 and 100." ,
137- " Error" , " OK" , " Error"
138- )
206+ [System.Windows.Forms.MessageBox ]::Show(" Quality must be an integer between 0 and 100." , " Error" , " OK" , " Error" )
139207 return
140208 }
141209
142210 if ($quality -lt 0 -or $quality -gt 100 ) {
143- [System.Windows.Forms.MessageBox ]::Show(
144- " Quality must be between 0 and 100." ,
145- " Error" , " OK" , " Error"
146- )
211+ [System.Windows.Forms.MessageBox ]::Show(" Quality must be between 0 and 100." , " Error" , " OK" , " Error" )
147212 return
148213 }
149- # ------------------------------------------
150214
151215 $format = $comboFormat.SelectedItem
152216 $deleteOriginals = $checkDelete.Checked
153217 $recursive = $checkRecursive.Checked
154218
155219 $logBox.Clear ()
156- Add-Log " Starting conversion to $format ..." $logBox
220+ Add-Log " Starting conversion..." $logBox
221+ Add-Log " Folder: $folder " $logBox
222+ Add-Log " Format: $format " $logBox
223+ Add-Log " Quality: $quality " $logBox
224+ Add-Log " Recursive: $recursive " $logBox
225+ Add-Log " Delete originals: $deleteOriginals " $logBox
157226 Add-Log " " $logBox
158227
159228 $buttonStart.Enabled = $false
160229
161230 try {
162231 if ($recursive ) {
163232 $files = Get-ChildItem - Path $folder - File - Recurse | Where-Object {
164- $_.Extension -in ' .jpg' , ' .jpeg' , ' .png' , ' .avif' , ' .JPG' , ' .JPEG' , ' .PNG' , ' .AVIF'
233+ $_.Extension -in ' .jpg' , ' .jpeg' , ' .png' , ' .avif' , ' .JPG' , ' .JPEG' , ' .PNG' , ' .AVIF'
165234 }
166235 } else {
167236 $files = Get-ChildItem - Path $folder - File | Where-Object {
168- $_.Extension -in ' .jpg' , ' .jpeg' , ' .png' , ' .avif' , ' .JPG' , ' .JPEG' , ' .PNG' , ' .AVIF'
237+ $_.Extension -in ' .jpg' , ' .jpeg' , ' .png' , ' .avif' , ' .JPG' , ' .JPEG' , ' .PNG' , ' .AVIF'
169238 }
170239 }
171240
172241 $total = $files.Count
173242 $success = 0
174243 $fail = 0
175244
176- if ($total -eq 0 ) {
177- Add-Log " No PNG/JPG/JPEG/AVIF files found." $logBox
178- } else {
179- Add-Log " Found $total file(s)." $logBox
180- Add-Log " " $logBox
245+ foreach ($file in $files ) {
246+ $outPath = [System.IO.Path ]::ChangeExtension($file.FullName , " .$format " )
181247
182- foreach ($file in $files ) {
248+ Add-Log " Converting: $ ( $file.Name ) " $logBox
183249
184- $outPath = [ System.IO.Path ]::ChangeExtension( $ file.FullName , " . $format " )
250+ & magick $ file.FullName - auto - orient - quality $quality $outPath
185251
186- Add-Log " Converting: $ ( $file.FullName ) " $logBox
187- Add-Log " --> $outPath " $logBox
188-
189- & magick $file.FullName - auto- orient - quality $quality $outPath
190-
191- if (Test-Path $outPath ) {
192- if ($deleteOriginals ) {
193- Remove-Item $file.FullName - ErrorAction SilentlyContinue
194- }
195- $success ++
196- Add-Log " OK" $logBox
197- } else {
198- $fail ++
199- Add-Log " ERROR: output not created." $logBox
252+ if (Test-Path $outPath ) {
253+ if ($deleteOriginals ) {
254+ Remove-Item $file.FullName - ErrorAction SilentlyContinue
200255 }
201-
202- Add-Log " " $logBox
256+ $success ++
257+ Add-Log " OK" $logBox
258+ } else {
259+ $fail ++
260+ Add-Log " ERROR" $logBox
203261 }
204-
205- Add-Log " -----------------------------" $logBox
206- Add-Log " Done." $logBox
207- Add-Log " Total: $total " $logBox
208- Add-Log " Success: $success " $logBox
209- Add-Log " Failed: $fail " $logBox
210262 }
263+
264+ Add-Log " " $logBox
265+ Add-Log " Done." $logBox
266+ Add-Log " Total: $total " $logBox
267+ Add-Log " Success: $success " $logBox
268+ Add-Log " Failed: $fail " $logBox
211269 }
212270 finally {
213271 $buttonStart.Enabled = $true
0 commit comments