Skip to content

Instantly share code, notes, and snippets.

@saggie
Last active January 1, 2017 09:36
Show Gist options
  • Save saggie/796f4f14c051254c880f671d01cfcf88 to your computer and use it in GitHub Desktop.
Save saggie/796f4f14c051254c880f671d01cfcf88 to your computer and use it in GitHub Desktop.
PowerShell と C# で画像処理(ピクセル操作) ref: http://qiita.com/saggie/items/2cc1cc89830c1184ab75
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)
$grayValue = [byte](($pixel.r + $pixel.g + $pixel.b) / 3)
PS C:\> & .\ConvertTo-GrayScale.ps1 neko.jpg
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