学祭で自作プリクラ(笑)を展示しました


去年も展示したのですが、今年は数カ所手を加えました。(とか言いつつ実は7割作り直し
印刷含め、全て無料です。インク、シール代は部費で賄っております(インク代の半分は自費
環境はVisualStudio2008,言語はC#



送信者 作品
手作り感あふれるOP画面。
カーくんに描いて頂きました。本当に有難う。


送信者 作品
撮影画面。今年の変更部分その1。
去年はカメラの映像の上にフレームを合成出来なかったので、今年はそこを実装しました。
写ってるのは元バイト先と俺の腕。
使用しているフレームは、去年キョウに描いてもらったものです。


USBカメラの映像に静止画を合成しつつキャプチャするのに
DirectShow,VMR9を利用しています。
・・・とかいいつつ、「M.Oshikiri HomePage Tips集」のM.Oshikiri様のDShowLibを使わせて頂き、大分楽をしております。
サンプルも十分あり、お陰さまで僅か2日でこの部分を完成させる事が出来ました。
http://www.geocities.co.jp/SiliconValley/7406/tips/index.html


送信者 作品
今年の変更部分その2.
ペイント、スタンプ機能を追加しました。
無限アンドゥ、初期化も可能です(学祭中バグがありましたが、学祭後直しました(遅


ペイント、スタンプ機能のマウスのイベント処理は、
「プログラミング色々」のいなば様のお絵かきクラスを参考にさせて頂きました。
http://7ujm.net/index.html
http://7ujm.net/CSharp/draw.html
無限アンドゥ、初期化、スタンプに対応するために、
ペンの座標履歴を保持するListとBitmapの管理などは手を加えています。


マウスのボタンを押した時のイベント。
アンドゥ用のBitmapをListに追加する。
エンピツ(?)モードならこの時の座標を保存しておく。
スタンプモードなら、この時にスタンプを編集用bitmapに描画する。

private void _MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
    if (e.Button == System.Windows.Forms.MouseButtons.Left )
    {
        undoList.Add(new Bitmap(undoList[undoList.Count - 1]));

        if(mode == PaintMode.Pencil)
        {
            pos.i_stX = DrawPointX(e.X);
            pos.i_stY = DrawPointY(e.Y);
        }
        if (mode == PaintMode.Stamp)
        {
            if (stampListView.SelectedItems.Count == 0) return;

            String path = "./stamps/" + stampListView.SelectedItems[0].Text.Split('\\')[1];
            using(Bitmap stamp = new Bitmap(path) )
            using(Graphics eg = Graphics.FromImage(undoList[undoList.Count - 1]))
            {
                eg.DrawImage(stamp, DrawPointX(e.X) - (int)(stamp.Width / 2.0), DrawPointY(e.Y) - (int)(stamp.Height / 2.0));
            }
         }
    } 
}


PaintBoxのペイントイベント時に呼び出される。
編集用BitmapをPictureBoxに描画する。
ペンの座標データが溜まってる時はそれを編集用Bitmapに描画したのちにPictureBoxに描画。
ここでarをクリアしてしまおうとしたが、
これをすると線と線の隙間が目立つので辞めた。

private void _Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
    //foreach使えばよかた
    for (int i = 0; i < ar.Count; i++)
    {
        data d_pos = ar[i];
        System.Drawing.Pen pen = new System.Drawing.Pen(d_pos.lineColor, lineWidth);
        System.Drawing.Point pt1 = new System.Drawing.Point(d_pos.i_stX, d_pos.i_stY);
        System.Drawing.Point pt2 = new System.Drawing.Point(d_pos.i_enX, d_pos.i_enY);

        using (Graphics eg = System.Drawing.Graphics.FromImage(undoList[undoList.Count - 1]))
        {
            eg.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
            eg.DrawLine(pen, pt1, pt2);
        }
    }
    //ar.Clear();これするとDrawLineの隙間が目立つ
    e.Graphics.DrawImage(undoList[ undoList.Count-1] , 0, 0, e.ClipRectangle.Width, e.ClipRectangle.Height );
}

最後の要素を指定するために「undoList.Count-1」がキモくてしかたなかった。
ListもC++vectorみたいにbackメンバ関数くれよ〜とか思ってたけど、、、
Stackェ・・・
まぁ深夜作業なので仕方ない(うぉぃ


arはマウスのボタンが押上した時にクリアする事にした。

private void _MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
{
    if (e.Button == System.Windows.Forms.MouseButtons.Left)
    {
        ar.Clear();
    }
}


印刷やフレーム、スタンプのサムネイル方法については、DOBON.NET様ほとんどそのまんまです。


その他、「いんさつ」「はじめるよ」などのボタンは
Hyper Banner Makerを利用しました。
手軽にきれいなバナーが作れます。
バナー自動作成


作り直しとはいえ、
僅か5日間で実装出来たのは、
.NET Frameworkの生産性の高さだけでなく、
ウェブサイトにて様々な情報、ライブラリ、ツールを提供して下さる開発者皆様のおかげです。
本当にありがとうございます。


そして、フレームやスタンプ、食料調達などなど協力してくださった皆様、
ありがとうございました。