C#でRGB画像をRGBAに変換するCLIコマンド

C# コンピュータ
C#

実行環境構築

プロジェクトの作成

mkdir プロジェクト名
cd プロジェクト名
dotnet new console
dotnet add package System.Drawing.Common

ソースプログラム

using System.Drawing;
using System.Drawing.Imaging;

namespace adda
{
    class Program
    {
        
        // アルファチャンネルの追加
        static int adda(string src_file)
        {
            if (!OperatingSystem.IsWindows()) return 1;

            string bak_file = src_file + ".bak";
            System.IO.File.Move(src_file, bak_file);
            string dst_file = src_file;

            using var fs = new FileStream(bak_file, FileMode.Open);
            using Bitmap bmp = new Bitmap(fs);
            using Bitmap bmp2 = new Bitmap(bmp.Width, bmp.Height, PixelFormat.Format32bppArgb);

            if (bmp.PixelFormat != PixelFormat.Format24bppRgb)
            {
                fs.Close();
                System.IO.File.Move(bak_file, dst_file);
                return 1; // 24bitRGB以外は未対応
            }
                
            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
            );
            
            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 * 3;
                    int pos2 = y * bmpd2.Stride + x * 4;
                    
                    pixels2[pos2] = pixels[pos];
                    pixels2[pos2+1] = pixels[pos+1];
                    pixels2[pos2+2] = pixels[pos+2];
                    pixels2[pos2+3] = 255;
                }
            }                   
            
            System.Runtime.InteropServices.Marshal.Copy(pixels2,0,bmpd2.Scan0,pixels2.Length);
            bmp.UnlockBits(bmpd);
            bmp2.UnlockBits(bmpd2);
            
            bmp2.Save(dst_file, ImageFormat.Png);

            fs.Close();
            System.IO.File.Delete(bak_file);
            return 0;
        }
        
        // アプリケーションのエントリポイント
        static int Main(string[] args)
        {
            if (!OperatingSystem.IsWindows()) return 1;

            var src_file = "";
            
            if (args.Length == 0)
            {
                Console.WriteLine("AddAlpha.exe PNGファイルのパス");
                return 1; // 異常終了
            }

            int result = 0;
            for(var i=0; i < args.Length; i++)
            {
                src_file = args[i];
                if (System.IO.Path.GetExtension(src_file).ToUpper() != ".PNG") continue;
                Console.WriteLine("{0}", src_file);
                result += adda(src_file);
            }
            
            return result;
        }
    }
}

ビルド

dotnet build -c Release

使い方

AddAlpha.exe "画像ファイルのパス" ["画像ファイルのパス"...]
ビルドで作成された実行ファイルをエクスプローラーの「送る」にショートカットを作成

コメント