なんとなく、ふわっと・・

写真と画像処理関係とひとりごとをなんとなく書き溜めていきたい

Candy

2008-01-31 00:22:19 | 写真

直径数ミリの小さな花。 でもなんだか、キャンディーみたいでおいしそう。


吾妻3、つくば市



[DFA Macro 100mmF2.8]


Comment

Y

2008-01-31 00:13:37 | rinkaku




Comment

アルファ値とクリップボード

2008-01-31 00:02:51 | C#(Graphics)

アルファチャネルを持つ画像をクリップボードを経由してやり取りしたい。

普通に SetImage() と GetImage() を使うとうまくいかない。 ちょっとやってみよう。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

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

namespace Clipboard32
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Bitmap bmp = new Bitmap(200, 200, PixelFormat.Format32bppArgb);

            Graphics g = Graphics.FromImage(bmp);
            g.SmoothingMode = SmoothingMode.AntiAlias;
            g.FillEllipse(Brushes.Crimson, 10, 10, 180, 180);
            g.Dispose();

            g = this.CreateGraphics();
            g.DrawImage(bmp, 10, 10);
            g.Dispose();

            Clipboard.SetImage(bmp);

            bmp.Dispose();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (Clipboard.ContainsImage())
            {
                Bitmap bmp = (Bitmap)Clipboard.GetImage();

                Graphics g = this.CreateGraphics();
                g.DrawImage(bmp, 10, 220);
                g.Dispose();

                bmp.Dispose();
            }
            else
                MessageBox.Show("There is no Image in the Clipboard!");
        }
    }
}


button1 を押してから、button2 を押すと



のようになり、GetImage() でクリップボードからえられるビットマップは、本来、透過している
部分が青になってしまいアルファ値が無視される。 MSPaint に貼り付けると



となり、同じくアルファ値が無視されている。 また、Windows のユーティリティー Clipbrd.exe を
つかって、クリップボードを内容を見てみると



となっており、クリップボードが勝手にレンダリングしてアルファ値を失っている。

WEB を検索してみると、この問題は FAQ であることが分かるが、回避策のコードを探し出せなかった。

そこで、ここを参考にして、内部に Bitmap を抱えたクラスをつくり、そのインスタンスをカスタムフォーマット
としてクリップボードを介してやり取りすることを試してみた。

        private void button3_Click(object sender, EventArgs e)
        {
            Bitmap bmp = new Bitmap(200, 200, PixelFormat.Format32bppArgb);

            Graphics g = Graphics.FromImage(bmp);
            g.SmoothingMode = SmoothingMode.AntiAlias;
            g.FillEllipse(Brushes.Crimson, 10, 10, 180, 180);
            g.Dispose();

            g = this.CreateGraphics();
            g.DrawImage(bmp, 10, 10);
            g.Dispose();

            Bitmap32 bmp32 = new Bitmap32(bmp);
            Clipboard.SetData("Bitmap32Format", bmp32);

            bmp.Dispose();
        }

        private void button4_Click(object sender, EventArgs e)
        {
            if (Clipboard.ContainsData("Bitmap32Format"))
            {
                Bitmap32 bmp32 = Clipboard.GetData("Bitmap32Format") as Bitmap32;
                Bitmap bmp = bmp32.Bmp32;

                Graphics g = this.CreateGraphics();
                g.DrawImage(bmp, 10, 220);
                g.Dispose();

                bmp.Dispose();
            }
        }
    }

    [Serializable]
    public class Bitmap32
    {
        private Bitmap bmp = null;

        public Bitmap32(Bitmap bmp32)
        {
            bmp = bmp32;
        }

        ~Bitmap32()
        {
            if (bmp != null) { bmp.Dispose(); }
        }

        public Bitmap Bmp32
        {
            get
            {
                return bmp.Clone() as Bitmap;
            }

            set
            {
                if (bmp != null) { bmp.Dispose(); }
                bmp = value.Clone() as Bitmap;
            }
        }
    }


この結果は



となり、うまくいく。 当然、カスタムフォーマットなので、他のアプリケーションには貼り付けられない。



このようにして、すくなくとも自作の C# アプリケーション間では、アルファ値を保ったままクリップボードを
介したやり取りができるようになった。

さらに進んで、Bitmap オブジェクトそのものをカスタムフォーマットとしてやり取りすることを試した。

        private void button5_Click(object sender, EventArgs e)
        {
            Bitmap bmp = new Bitmap(200, 200, PixelFormat.Format32bppArgb);

            Graphics g = Graphics.FromImage(bmp);
            g.SmoothingMode = SmoothingMode.AntiAlias;
            g.FillEllipse(Brushes.Crimson, 10, 10, 180, 180);
            g.Dispose();

            g = this.CreateGraphics();
            g.DrawImage(bmp, 10, 10);
            g.Dispose();

            Clipboard.SetData("Bitmap32Format2", bmp);

            bmp.Dispose();
        }

        private void button6_Click(object sender, EventArgs e)
        {
            if (Clipboard.ContainsData("Bitmap32Format2"))
            {
                Bitmap bmp = Clipboard.GetData("Bitmap32Format2") as Bitmap;

                Graphics g = this.CreateGraphics();
                g.DrawImage(bmp, 10, 220);
                g.Dispose();

                bmp.Dispose();
            }
        }


結果は、



となり、うまくいく。

この方法では、パレットをもったビットマップの場合でも、その情報を失わずにやり取りできるだろう。


Comment