Quantcast
Channel: xlogI125’s blog
Viewing all articles
Browse latest Browse all 55

モノクロビットマップファイルの色を変更 BitmapSource.Palette

$
0
0

モノクロビットマップファイルのカラーパレットを変更した画像をPNGファイルとして保存する方法を考える。

モノクロビットマップファイルはペイントでファイルの種類を「モノクロ ビットマップ」として保存したものを使用する。

カラーパレットを指定するのでBitmapSource.FormatPixelFormats.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() }
  }

}

Viewing all articles
Browse latest Browse all 55

Trending Articles