2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

PowerShell でオレオレカラーピッカー

Last updated at Posted at 2018-02-25

概要

Windows PowerShell 用のカラーピッカー関数を作成してみました。
PowerShell v2.0 以降なら動くと思います。

実行するとコンソールに以下のように表示されます(型はSystem.Drawing.Color です)。

Qiitaのヘッダー色
R             : 85
G             : 197
B             : 0
A             : 255
IsKnownColor  : False
IsEmpty       : False
IsNamedColor  : False
IsSystemColor : False
Name          : ff55c500

注意事項

  • 今時System.Windows.FormSystem.Drawingを使用しています
  • System.Windows.Formを使用しているため、PowerShell v2.0ではSTAモードで起動する必要があります
  • マルチディスプレイ環境で試していないため意図しない動作をする可能性があります

コード

# 必要なアセンブリロード
Add-Type -AssemblyName System.Windows.Forms, System.Drawing

<#
.Synopsis
カーソルのある位置の色を System.Drawing.Color として取得する

.EXAMPLE
PS > Select-DisplayColor
# 現在のマウスの位置の色を取得

.EXAMPLE
PS > Select-DisplayColor -WaitUserSelect
# ユーザーがクリックするまで待機して、クリックした位置の色を取得

.OUTPUTS
System.Drawing.Color
# >
function Select-DisplayColor {
    [CmdletBinding()]param (
        # 指定するとユーザーがクリックするまで処理を待機し、クリックした色の位置を返す
        [switch]$WaitUserSelect,

        # 基準の位置。既定は現在のカーソルの位置
        [Drawing.Point]$PickPoint = [Windows.Forms.Cursor]::Position   
    )
    
    # 画面キャプチャ
    [Drawing.Rectangle]$scrRect = [Windows.Forms.Screen]::FromPoint( $PickPoint ).Bounds
    
    [Drawing.Bitmap]$scrBmp = 
        New-Object -TypeName Drawing.Bitmap -ArgumentList $scrRect.Width, $scrRect.Height
    
    [Drawing.Graphics]$gpc = [Drawing.Graphics]::FromImage( $scrBmp )
    $gpc.CopyFromScreen(
            $scrRect.Location.X, $scrRect.Location.Y, # Source
            0, 0, # Dest
            $scrRect.Size)
    $gpc.Dispose()
    

    [Drawing.Color]$selectColor = [Drawing.Color]::Empty
    if ( !$WaitUserSelect ) {
        $selectColor = $scrBmp.GetPixel( $PickPoint.X , $PickPoint.Y )
        $scrBmp.Dispose()
        return $selectColor
    }

    # 画面を覆うフォームを作成
    [Windows.Forms.Form]$frm = 
        New-Object -TypeName Windows.Forms.Form -Property @{
            BackgroundImage = $scrBmp
            FormBorderStyle = [Windows.Forms.FormBorderStyle]::None
            WindowState     = [Windows.Forms.FormWindowState]::Maximized
        }
    
    # クリックイベント定義
    $frm.add_Click({
        try {
            [Drawing.Bitmap]$bmp = $this.BackgroundImage
            
            # 1階層親のスコープの変数に値をセット
            Set-Variable -Name selectColor -Scope 1 -Value $bmp.GetPixel( $_.X, $_.Y )
        } finally { $this.Close() }
    })
    
    $frm.ShowDialog() > $null
    $frm.Dispose() ; $scrBmp.Dispose()
    Write-Output -InputObject $selectColor
}

使用例

Qiitaのヘッダー部分にカーソルを置いて実行すると、以下の結果になります。

PS C:\> Select-DisplayColor


R             : 85
G             : 197
B             : 0
A             : 255
IsKnownColor  : False
IsEmpty       : False
IsNamedColor  : False
IsSystemColor : False
Name          : ff55c500

WaitUserSelectスイッチを指定すると、画面キャプチャをしたフォームを表示して、クリックした位置から色を取得します。

PS C:\> Select-DisplayColor -WaitUserSelect #「投稿する」などの濃い緑色の部分をクリック


R             : 59
G             : 138
B             : 0
A             : 255
IsKnownColor  : False
IsEmpty       : False
IsNamedColor  : False
IsSystemColor : False
Name          : ff3b8a00

その他

WaitUserSelectスイッチを指定時に、フォームのクリックイベントで色を取得しています。
しかし、イベント処理の中から関数内の変数を直接変更できないため

# 1階層親のスコープの変数に値をセット
Set-Variable -Name selectColor -Scope 1 -Value $bmp.GetPixel( $_.X, $_.Y )

のように無理矢理、値を設定しているのが気になります。
もう少し上手い手はあるのでしょうか……

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?