画像のピクセルを一つ一つ拾い上げコピーするサンプルになります。
出来上がったプログラムそのものは低速で画像ファイルのみコピーする代物で実用性は皆無です。
ただ、ピクセル単位でアクセスしていますので、こちらプログラムをベースに画像を加工などに使えると思います。
ソース
ファイル名:image_copy.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
namespace histogram
{
class Program
{
static void CopyImage(string inFile, string outFile)
{
using (var bmp = new Bitmap(inFile))
using (var bmp2 = new Bitmap(bmp.Width, bmp.Height, bmp.PixelFormat))
{
var bmpd = bmp.LockBits(
new Rectangle(0, 0, bmp.Width, bmp.Height),
ImageLockMode.ReadWrite,
bmp.PixelFormat
);
var bmpd2 = bmp2.LockBits(
new Rectangle(0, 0, bmp2.Width, bmp2.Height),
ImageLockMode.ReadWrite,
bmp2.PixelFormat
);
//Console.WriteLine("bmpd.Stride:{0},bmp.Width:{1}", bmpd.Stride,bmp.Width);
var byteWidth = (int)(bmpd.Stride / bmp.Width);
//Console.WriteLine("byte:{0}", byteWidth);
byte[] pixels = new byte[bmpd.Stride * bmp.Height];
byte[] pixels2 = new byte[bmpd2.Stride * bmp2.Height];
System.Runtime.InteropServices.Marshal.Copy(bmpd.Scan0, pixels, 0, pixels.Length);
// 先頭からループ
for (int y = 0; y < bmp.Height; y++)
{
for (int x = 0; x < bmpd.Width; x++)
{
int pos = y * bmpd.Stride + x * byteWidth;
for (int i = 0; i < byteWidth; i++)
{
pixels2[pos+i] = pixels[pos+i];
}
}
}
System.Runtime.InteropServices.Marshal.Copy(pixels2,0,bmpd2.Scan0,pixels2.Length);
bmp.UnlockBits(bmpd);
bmp2.UnlockBits(bmpd2);
bmp2.Save(outFile, bmp.RawFormat);
}
}
static void Main(string[] args)
{
if (args.Length == 0)
{
return;
}
var inFile = args[0];
var outFile = args[1];
Console.WriteLine("in:{0},out:{1}", inFile, outFile);
CopyImage(inFile, outFile);
}
}
}
コンパイル
PS>csc image_copy.cs
実行
PS>.\image_copy.exe <コピー元> <コピー先>
試したところ画像ファイルは出来上がりましたが、ファイルサイズがコピー元のサイズと微妙に異なっていましたので、単純なファイルコピーとは異なるようです。
コメント