I am trying to make an upscale texture mod for an old game "Recoil".
For this, I need to find the height, width, pixel format and colour count of a few 1000 images, so that I can feed this information to excel and find the best textures to be upscaled.
I have been able to get the height, width and pixel format via a PowerShell script, which I can then copy to excel as this script provides a table. the script works on the whole folder.
Function Get-Image{
Param(
[Parameter(ValueFromPipeline=$true)]
[System.IO.FileINfo]$file
)
begin{
[System.Reflection.Assembly]::LoadWithPartialName("System.Drawing") |Out-Null
}
process{
if( $file.Exists){
$img=[System.Drawing.Image]::FromFile($file)
$image=$img.Clone()
$img.Dispose()
$image | Add-Member `
-MemberType NoteProperty `
-Name Filename `
-Value $file.FUllname `
-PassThru
}else{
Write-Host "File not found: $file" -fore yellow
}
}
end{}
}
dir C:\test\*.png | Get-Image
dir C:\test\*.png -Recurse | Get-Image | select filename, Width, Height, PixelFormat | ft -auto
I need help finding a way to get a colour count of the images. I have found a manual way to do it via a Photoshop filter but it is not a viable way to do all the images. photoshop filter example
If I can get the Colour count in a similar way to the code provided it would be the best.
edit: I need a way to get Colour count of all images in the folder.
the images themselves are small (the biggest being 512x512). I just need the number of colours, no need for the breakdown of RGB.
ps- I have literally no knowledge of programming and scripting ( even the above script someone Reddit helped me out with)
Hopefully, I have been able to explain my query clearly. Thank you for your time and consideration.
CodePudding user response:
Use the GetPixel()
method to fetch the color used for each pixel, then count the unique colors you encounter:
$hashset = [System.Collections.Generic.HashSet[System.Drawing.Color]]::new()
foreach($x in 0..($image.Width - 1)){
foreach($y in 0..($image.Height - 1)){
[void]$hashset.Add($image.GetPixel($x, $y))
}
}
Write-Host "Image has $($hashset.Count) unique colors"
You could add this routine to your existing function like so:
process {
if ($file.Exists) {
# Load image
$img = [System.Drawing.Image]::FromFile($file)
$image = $img.Clone()
$img.Dispose()
# Count colors
$colorSet = [System.Collections.Generic.HashSet[System.Drawing.Color]]::new()
foreach ($x in 0..($image.Width - 1)) {
foreach ($y in 0..($image.Height - 1)) {
[void]$colorSet.Add($image.GetPixel($x, $y))
}
}
# Add file name and color count properties to image object
$fileNameProp = @{ MemberType = 'NoteProperty'; Name = 'Filename'; Value = $file.FullName; PassThru = $true}
$colorCountProp = @{ MemberType = 'NoteProperty'; Name = 'ColorCount'; Value = $colorSet.Count; PassThru = $true}
$image | Add-Member @fileNameProp | Add-Member @colorCountProp
}
else {
Write-Host "File not found: $file" -fore yellow
}
}
And now you can do:
dir C:\test\*.png -Recurse | Get-Image | ft Filename, Width, Height, PixelFormat, ColorCount -AutoSize