Last active
January 1, 2017 09:36
-
-
Save saggie/796f4f14c051254c880f671d01cfcf88 to your computer and use it in GitHub Desktop.
PowerShell と C# で画像処理(ピクセル操作) ref: http://qiita.com/saggie/items/2cc1cc89830c1184ab75
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
param( | |
[Parameter(Mandatory = $true)] | |
[string] | |
$SourceImageFilePath | |
) | |
# 画像ファイルのパスを解決 | |
$resolvedFilePath = Resolve-Path $SourceImageFilePath | |
# 画像の情報を取得 | |
Add-Type -AssemblyName System.Drawing | |
$sourceImage = [System.Drawing.Image]::FromFile($resolvedFilePath) | |
$imageWidth = $sourceImage.Width | |
$imageHeight = $sourceImage.Height | |
# 'ImagingUtil.cs' をロード | |
$thisDirectoryPath = Split-Path $MyInvocation.MyCommand.Path -Parent | |
Add-Type -Path (Join-Path $thisDirectoryPath 'ImagingUtil.cs') ` | |
-ReferencedAssemblies System.Drawing | |
# 画像データをピクセルデータに変換 | |
$pixels = [ImagingUtil.BitmapConverter]::ConvertBitmapToPixels($sourceImage) | |
if ($sourceImage -ne $null) | |
{ | |
$sourceImage.Dispose() | |
} | |
# 画像処理 (グレースケール変換) | |
foreach ($pixel in $pixels) | |
{ | |
$grayValue = [byte](($pixel.r + $pixel.g + $pixel.b) / 3) | |
$pixel.r = $grayValue | |
$pixel.g = $grayValue | |
$pixel.b = $grayValue | |
} | |
# ピクセルデータを画像データに戻す | |
$outputImage = [ImagingUtil.BitmapConverter]::ConvertPixelsToBitmap($pixels, $imageWidth, $imageHeight) | |
# 変換した画像データを保存する(元画像と同じ場所に、ファイル名の末尾に "_gray" と付けて保存) | |
$outputFileLocation = Split-Path $resolvedFilePath -Parent | |
$outputFileBaseName = (Get-ChildItem $resolvedFilePath).BaseName + "_gray" | |
$outputFileExtention = (Get-ChildItem $resolvedFilePath).Extension | |
$outputFileFullName = $outputFileBaseName + $outputFileExtention | |
$outputFilePath = Join-Path $outputFileLocation $outputFileFullName | |
$outputImageFormat = [ImagingUtil.ImageFormatResolver]::ResolveFromExtension($outputFileExtention) | |
$outputImage.Save($outputFilePath, $outputImageFormat) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$grayValue = [byte](($pixel.r + $pixel.g + $pixel.b) / 3) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
PS C:\> & .\ConvertTo-GrayScale.ps1 neko.jpg |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Drawing; | |
using System.Drawing.Imaging; | |
using System.Runtime.InteropServices; | |
namespace ImagingUtil | |
{ | |
// RGBA のバイト情報をピクセル単位で扱えるようにするためのクラス | |
public class Pixel | |
{ | |
public byte a; | |
public byte r; | |
public byte g; | |
public byte b; | |
public Pixel(byte b, byte g, byte r, byte a) | |
{ | |
this.a = a; | |
this.r = r; | |
this.g = g; | |
this.b = b; | |
} | |
} | |
// ビットマップとピクセルデータ間の変換処理を行うクラス | |
public static class BitmapConverter | |
{ | |
// ビットマップをピクセルデータに変換する | |
public static IList<Pixel> ConvertBitmapToPixels(Bitmap bitmap) | |
{ | |
byte[] byteArray = null; | |
using (bitmap) | |
{ | |
byteArray = ConvertBitmapToByteArray(bitmap); | |
} | |
var ret = new List<Pixel>(); | |
for (var i = 0; i < byteArray.Length; i += 4) | |
{ | |
ret.Add(new Pixel(byteArray[i + 0], | |
byteArray[i + 1], | |
byteArray[i + 2], | |
byteArray[i + 3])); | |
} | |
return ret; | |
} | |
// ビットマップをバイト配列に変換する | |
private static byte[] ConvertBitmapToByteArray(Bitmap bitmap) | |
{ | |
var ret = new byte[bitmap.Width * bitmap.Height * 4]; | |
BitmapData bitmapData = bitmap.LockBits( | |
new Rectangle(0, 0, bitmap.Width, bitmap.Height), | |
ImageLockMode.ReadOnly, | |
PixelFormat.Format32bppArgb); | |
Marshal.Copy(bitmapData.Scan0, ret, 0, ret.Length); | |
bitmap.UnlockBits(bitmapData); | |
return ret; | |
} | |
// ピクセルデータをビットマップに戻す | |
public static Bitmap ConvertPixelsToBitmap(IList<Pixel> pixels, int width, int height) | |
{ | |
var byteArray = new byte[width * height * 4]; | |
var index = 0; | |
foreach (var pixel in pixels) | |
{ | |
byteArray[index++] = pixel.b; | |
byteArray[index++] = pixel.g; | |
byteArray[index++] = pixel.r; | |
byteArray[index++] = pixel.a; | |
} | |
return ConvertByteArrayToBitmap(byteArray, width, height); | |
} | |
// バイト配列をビットマップに戻す | |
private static Bitmap ConvertByteArrayToBitmap(byte[] byteArray, int width, int height) | |
{ | |
Bitmap ret = new Bitmap(width, height); | |
BitmapData bitmapData = ret.LockBits( | |
new Rectangle(0, 0, ret.Width, ret.Height), | |
ImageLockMode.ReadWrite, | |
PixelFormat.Format32bppArgb); | |
Marshal.Copy(byteArray, 0, bitmapData.Scan0, byteArray.Length); | |
ret.UnlockBits(bitmapData); | |
return ret; | |
} | |
} | |
// 画像ファイルの保存形式 ImageFormat を決定するクラス | |
public static class ImageFormatResolver | |
{ | |
// 画像ファイルの拡張子から決定する | |
public static ImageFormat ResolveFromExtension(string extension) | |
{ | |
switch (extension.ToLower()) | |
{ | |
case ".bmp": return ImageFormat.Bmp; | |
case ".gif": return ImageFormat.Gif; | |
case ".jpg": | |
case ".jpeg": return ImageFormat.Jpeg; | |
case ".png": | |
default: return ImageFormat.Png; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment