モノクロビットマップファイルのカラーパレットを変更した画像をPNGファイルとして保存する方法を考える。
モノクロビットマップファイルはペイントでファイルの種類を「モノクロ ビットマップ」として保存したものを使用する。
カラーパレットを指定するのでBitmapSource.Format
はPixelFormats.BlackWhite
ではなくPixelFormats.Indexed1
とする。
. { # PowerShell 5.1, Windows 11 (2025年2月頃)$ErrorActionPreference=[System.Management.Automation.ActionPreference]::Stop Set-StrictMode -Version Latest Add-Type -AssemblyName PresentationCore # 画像ファイルのパス$pathIn=$env:USERPROFILE+"\Desktop\tmp\test.bmp"$pathOut=$env:USERPROFILE+"\Desktop\tmp\test.png"# 黒色部分の色$A0=255; $R0=192; $G0=128; $B0=64# 白色部分の色$A1=64; $R1=128; $G1=192; $B1=255# カラーパレットを作成$palette=[System.Windows.Media.Imaging.BitmapPalette]::new( [System.Windows.Media.Color[]]@( [System.Windows.Media.Color]::FromArgb($A0,$R0,$G0,$B0),[System.Windows.Media.Color]::FromArgb($A1,$R1,$G1,$B1) ) ) $fIn=$nulltry { # 元のBMPファイルを開く$fIn=[System.IO.File]::OpenRead($pathIn) # デコーダ$dec=[System.Windows.Media.Imaging.BitmapDecoder]::Create($fIn,[System.Windows.Media.Imaging.BitmapCreateOptions]::PreservePixelFormat,[System.Windows.Media.Imaging.BitmapCacheOption]::Default) # BitmapFrameを取得$frm=$dec.Frames[0] # ビットの深さを確認if ($frm.Format.BitsPerPixel -ne1) { @($frm|Format-List|Out-String -Stream) -ne""|Write-Host -ForegroundColor Cyan throw } # データをコピー$stride=[int][System.Math]::Truncate(($frm.Format.BitsPerPixel *$frm.PixelWidth +7) /8) $pixels=[byte[]]::new($stride*$frm.PixelHeight) $frm.CopyPixels($pixels,$stride,0) # コピーしたデータから画像を新規作成$src=[System.Windows.Media.Imaging.BitmapSource]::Create($frm.PixelWidth,$frm.PixelHeight,$frm.DpiX,$frm.DpiY,[System.Windows.Media.PixelFormats]::Indexed1,$palette,$pixels,$stride) # エンコーダ$enc=[System.Windows.Media.Imaging.PngBitmapEncoder]::new() # IList<BitmapFrame>を設定$enc.Frames =[System.Windows.Media.Imaging.BitmapFrame[]]@([System.Windows.Media.Imaging.BitmapFrame]::Create($src)) # PNGファイルとして保存$fOut=$nulltry { $fOut=[System.IO.File]::OpenWrite($pathOut) $enc.Save($fOut) } finally { if ($null -ne$fOut) { $fOut.Dispose() } } } finally { # 元のBMPファイルを閉じるif ($null -ne$fIn) { $fIn.Dispose() } } # 保存したPNGファイルのプロパティを表示$f=$nulltry { $f=[System.IO.File]::OpenRead($pathOut) $s=[System.Windows.Media.Imaging.PngBitmapDecoder]::Create($f,[System.Windows.Media.Imaging.BitmapCreateOptions]::PreservePixelFormat,[System.Windows.Media.Imaging.BitmapCacheOption]::Default).Frames[0] @( @($f.Name |Format-List|Out-String -Stream) -ne"""" @($s|Format-List|Out-String -Stream) -ne"""" @($s.Format |Format-Table|Out-String -Stream) -ne"""" @($s.Palette.Colors |Format-Table|Out-String -Stream) -ne"""" @([PSCustomObject]@{ MmWidth =25.4*$s.PixelWidth /$s.DpiX; MmHeight =25.4*$s.PixelHeight /$s.DpiY } |Format-List|Out-String -Stream) -ne"" ) |Write-Host -ForegroundColor Yellow } finally { if ($null -ne$f) { $f.Dispose() } } }