【お知らせ】プログラミング記事の投稿はQiitaに移行しました。

オートシェイプで画像をコピー

オートシェイプを生成してクリップボードにコピーしてみました。引数でJPEG(複数可)を渡すとクリップボードにコピーされるので、Excelに貼り付けることが出来るようになります。コードをパブリックドメインで公開します。

using System;
using System.Drawing;
using System.IO;
using System.Text;
using System.Windows.Forms;

class Program
{
    [STAThread]
    static void Main(string[] args)
    {
        int n = args.Length, datasize = 0, fnsize = 0;
        if (n == 0) return;
        byte[][] fn = new byte[n][], data = new byte[n][];
        var bmp = new Bitmap[n];
        for (int i = 0; i < n; i++)
        {
            fn[i] = Encoding.Unicode.GetBytes(
                Path.GetFileNameWithoutExtension(args[i]) + '\0');
            data[i] = File.ReadAllBytes(args[i]);
            bmp[i] = new Bitmap(args[i]);
            datasize += data[i].Length;
            fnsize += fn[i].Length;
        }
        var ms = new MemoryStream();
        var bw = new BinaryWriter(ms);
        bw.Write(0xf000000f); bw.Write(40 + 69 * n + datasize);
        bw.Write(0xf0060000); bw.Write(0x18);
        bw.Write(0x401 + n); bw.Write(2); bw.Write(2); bw.Write(1);
        bw.Write(1); bw.Write(n + 1);
        bw.Write(0xf001001f); bw.Write(69 * n + datasize);
        for (int i = 0; i < n; i++)
        {
            bw.Write(0xf0070052); bw.Write(61 + data[i].Length);
            var guid = Guid.NewGuid().ToByteArray();
            bw.Write((ushort)0x0505); bw.Write(guid); bw.Write((ushort)0xff);
            bw.Write(25 + data[i].Length); bw.Write(1); bw.Write(0); bw.Write(0x10000 * (i + 1));
            bw.Write(0xf01d46a0); bw.Write(17 + data[i].Length);
            bw.Write(guid); bw.Write((byte)0xff); bw.Write(data[i]);
        }
        bw.Write(0xf002000f); bw.Write(72 + 68 * n + fnsize);
        bw.Write(0xf0080010); bw.Write(8); bw.Write(n + 1); bw.Write(0x401);
        bw.Write(0xf003000f); bw.Write(48 + 68 * n + fnsize);
        bw.Write(0xf004000f); bw.Write(0x28);
        bw.Write(0xf0090001); bw.Write(0x10); bw.Write(new byte[16]);
        bw.Write(0xf00a0002); bw.Write(8); bw.Write(0x400); bw.Write(5);
        for (int i = 0; i < n; i++)
        {
            bw.Write(0xf004000f); bw.Write(60 + fn[i].Length);
            bw.Write(0xf00a0002); bw.Write(8); bw.Write(0x401 + i); bw.Write(0xa00);
            bw.Write(0xf00b0023); bw.Write(12 + fn[i].Length);
            bw.Write((ushort)(0x4000 | 260)); bw.Write(i + 1);
            bw.Write((ushort)(0xc000 | 261)); bw.Write(fn[i].Length); bw.Write(fn[i]);
            bw.Write(0xf00e0000); bw.Write(0x10);
            int pos = i * 1600000 / 96; bw.Write(pos); bw.Write(pos);
            bw.Write(pos + bmp[i].Width * 100000 / 96);
            bw.Write(pos + bmp[i].Height * 100000 / 96);
            bmp[i].Dispose();
        }
        Clipboard.Clear();
        Clipboard.SetData("Office Drawing Shape Format", ms);
    }
}

これを応用すれば常に同じサイズで貼り付けたり自動で回転させたりすることもできるでしょう。エクスプローラ拡張などに組み込めば便利かもしれません。