[C#] クリップボードからビットマップ形式のデータを拾って、連番でフォルダに保存する

新人プログラマー向けシリーズ…ではなくて、チープだけど今まで手順が面倒だったのでツールに。

機能的には、クリップボードのビットマップ形式のデータを取り出して、特定のフォルダに連番で保存するだけで、という単発機能です。しかも、保存先はソースコードに書き込んでしまっているので、他で使う場合にはコンパイルし直さないという、私家版≒ダメツールです。設定ぐらいは後で、config に書き直すとして。

いままでの手順が、

  1. クリップボードで画面キャプチャ
  2. IrfanViewに貼り付け。
  3. ファイル名を「日付_連番」にして、特定のフォルダに保存
  4. エディタに [img 日付_連番] の形式で追加

だったのですが、1,2,3,4 は自動化できますよね。時々、2 で IrfanView に貼り付けた後に切り取ったり、縮小したりするので、必ずしも自動化とはいかないのですが、ほぼ1から4は同じ手順になっています。なので「ツール」にしてしまうということです。ブログへの up は、QX エディタで描いて、適当な perl スクリプトを通してアップします。その時に画像のサムネールやら拡大画像やらは C# で作った自作ツールです。なんで、こんなややこしい?ことになっているかというと、本当は Windows Live Writer で統一したいところなのですが、Live Wirter の場合はコードがうまく表示できない。Wordpress の場合は、インラインタグというのがあって、

1
...

と書くと、SyntaxHighlighter のプラグインを入れておけば、コードにハイライトを付けてくれます。これをローカルで編集する場合は、まあ、適当なテキストエディタのほうが良い訳で、、いくつかのツールを組み合わせて書いているという具合。あまり、ブラウザのエディタを使わないんですよね…というタイプなので。

■クリップボードからビットマップを取得する

1
2
3
4
5
6
7
8
9
private void buttonClip_Click(object sender, EventArgs e)
{
    var clip = Clipboard.GetDataObject();
    // 画像ファイルのみ取り込み
    var bmp = clip.GetData(typeof(Bitmap)) as Bitmap;
    if (bmp == null) return;
    // ピクチャへ表示
    pictureBox1.Image = bmp;
}

とするだけで ok。PictugeBox は自動で拡大されないように SizeMode を Zoom に変更しておきます。

# ここに矢印とか簡単に付けられるツールを作らないと。
# あと、切り取った場合は、切り取り線みたいなのとか。

■指定のフォルダに連番で保存する

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
private void buttonSave_Click(object sender, EventArgs e)
{
    Bitmap bmp = (Bitmap)pictureBox1.Image;
    if (bmp == null)
        return;
 
    ImageFormat fmt = ImageFormat.Bmp;
    if (radioButton1.Checked) fmt = ImageFormat.Bmp;
    if (radioButton2.Checked) fmt = ImageFormat.Jpeg;
    if (radioButton3.Checked) fmt = ImageFormat.Png;
    string fname = MakeFileName(fmt);
    bmp.Save(fname, fmt);
 
    textBox1.Text = "[img " + Path.GetFileName(fname) + "]";
 
}
 
string MakeFileName(ImageFormat fmt)
{
    string path = FOLDER ;
    DateTime dt = DateTime.Now;
    string dname = string.Format("{0:0000}{1:00}{2:00}", dt.Year, dt.Month, dt.Day);
    var files = System.IO.Directory.GetFiles(FOLDER);
    var file  = files.Where(f => f.IndexOf(dname + "_") > 0).Max();
    if ( file == null ) {
        path += dname + "_01." + fmt.ToString();
    } else {
        var mat = new Regex( @"_(d+).").Match(file);
        int num = int.Parse( mat.Groups[1].Value );
        num++;
        path += dname + "_" + num.ToString("00") + "." + fmt.ToString();
    }
    return path;
}

ファイル名がユニークであればよい、というのと拡張子に関係なく日付でソートしたい時がある(名前でソートをすると古い順になるので)連番のほうをインクリメントしていきます。ここでは、フォルダからファイルを拾ってきているのでだんだん遅くなってしまう可能性があるのですが、まあ、良しということで。これはツールの config に連番を付けてもよいのですが、手作業で番号を入れたい時にちょっと困るので、フォルダからいちいち拾ってきます。

■ショートカットを設定する

なんどか使ってみて追加した機能が、ショートカットです。「取り込み(V)」となっているので、Alt+V で取り込みボタンを押せるのですが、何度も、Ctrl+V と間違えて押します。コピー&ペーストだから、Ctrl+V のほうが自然なんですね。なので、自然なほうに合わせて、フォームの key 取得のところで Ctrl+V を有効にします。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
    if (e.Control == true)
    {
        if (e.KeyCode == Keys.V)
        {
            buttonClip_Click(sender, null);
        }
        else if (e.KeyCode == Keys.S)
        {
            buttonSave_Click(sender, null);
        }
    }
}

そのままだと、フォーカスのあるボタンにキーイベントが飛んでいくので、フォームの方に来るように Form の KeyPreview プロパティを True にするのを忘れずに。

ちなみに、QX エディタでの編集状態はこんな感じになっています。

# QX エディタで img のところにカーソルをあてるとプレビューができるプラグインとか作れないですかね?

サンプルソースはこちら
http://sdrv.ms/10qU0yT

zip ファイル

AutoSaveCap-v0.1-src.zip

# この SkyDrive への登録部分も手間を省きたいところ。

アイコンは、84個のデスクトップアイコン | アイコンを創造するアイコン素材専門館アイコンゲータ- から借りてます。

カテゴリー: 開発, C# パーマリンク