C#で画像ファイルをピクセル単位でコピーするサンプル

C# コンピュータ
C#

画像のピクセルを一つ一つ拾い上げコピーするサンプルになります。
出来上がったプログラムそのものは低速で画像ファイルのみコピーする代物で実用性は皆無です。
ただ、ピクセル単位でアクセスしていますので、こちらプログラムをベースに画像を加工などに使えると思います。

ソース

ファイル名: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 <コピー元> <コピー先>

試したところ画像ファイルは出来上がりましたが、ファイルサイズがコピー元のサイズと微妙に異なっていましたので、単純なファイルコピーとは異なるようです。

コメント