none
pngで画像の一部を透明にするには。 RRS feed

  • 質問

  • 100pixel×100pixelの不透明なpng画像があって、10pixel×10pixelの透明な画像をpoint(10,10)の位置に作りたいのですが、どうすればよいでしょうか。

    2008年11月3日 10:35

回答

  • SolidColorBrush のリファレンスに、
     
    名前空間: System.Windows.Media
    アセンブリ: PresentationCore (presentationcore.dll 内)

     

    と記載されていると思いますが、記載されているように presentationcore.dll を参照設定に加える必要があります。
    using 節の記述は、ソースコードの記述の省略等を宣言するものであって、using の記載の有無でライブラリが自動的に参照設定されるようなことはありません。
    逆に言えば、参照設定さえ行えば using は記載しなくても各クラスライブラリを利用することができます。
     
    また、上記無いようであれば、System.Drawing の名前空間だけでおさまる内容でしょうし、System.Windows.Media.SolidColorBrush ではなく、System.Drawing.SolidBrush を使用すればよいでしょう。
     
    ついでに、ブラシの破棄を using ブロックで行うように、
     
    Code Snippet
     
    using (Brush mySolidBrush = new SolidBrush(Color.FromArgb(255, 1, 1))
    {
      g.FillRectangle(mySolidBrush, 10, 10, 10, 10);
    }

     

     

     
    などとすると良いかもしれません。
     
    2008年11月4日 13:47

すべての返信

  • Code Snippet

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.IO;
    using System.Runtime.Serialization.Formatters.Binary;
    using System.Windows.Media;


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

            private void Form1_Load(object sender, EventArgs e)
            {
               Image initialImage;
                System.Reflection.Assembly myAssembly = System.Reflection.Assembly.GetExecutingAssembly();
              
                initialImage = new Bitmap(myAssembly.GetManifestResourceStream("testTransparentAppli.tMap.png"));

                using (Graphics g = Graphics.FromImage(initialImage))
                {
                    SolidColorBrush  mySolidColorBrush;
                    mySolidColorBrush.Color = Color.FromArgb(255, 1, 1);
                    g.FillRectangle(mySolidColorBrush, 10, 10, 10, 10);
                   initialImage.MakeTransparent(Color.FromArgb(255, 1, 1));
                   initialImage.Save("partiallyTransparent.png");
                }

            }
        }
    }

     

    http://msdn.microsoft.com/ja-jp/library/system.windows.media(VS.80).aspx

    http://dobon.net/vb/dotnet/graphics/maketransparent.html

    エラー
    エラー 1 型または名前空間名 'Media' は名前空間 'System.Windows' に存在しません。アセンブリ参照が不足しています。 C:\Users\Y\Documents\Visual Studio 2005\Projects\testTransparentAppli\testTransparentAppli\Form1.cs 10 22 testTransparentAppli

     

     

    MakeTransparentをつかって題意を果たそうとしましたが、SolidColorBrushの使用の為、「using System.Windows.Media;」を書き加えたところ、上記のエラーがでてしまいました。

    「アセンブリ参照が不足しています。」とはどういうことでしょうか。またどうすればよいでしょうか。よろしくお願いします。

    2008年11月4日 12:40
  • SolidColorBrush のリファレンスに、
     
    名前空間: System.Windows.Media
    アセンブリ: PresentationCore (presentationcore.dll 内)

     

    と記載されていると思いますが、記載されているように presentationcore.dll を参照設定に加える必要があります。
    using 節の記述は、ソースコードの記述の省略等を宣言するものであって、using の記載の有無でライブラリが自動的に参照設定されるようなことはありません。
    逆に言えば、参照設定さえ行えば using は記載しなくても各クラスライブラリを利用することができます。
     
    また、上記無いようであれば、System.Drawing の名前空間だけでおさまる内容でしょうし、System.Windows.Media.SolidColorBrush ではなく、System.Drawing.SolidBrush を使用すればよいでしょう。
     
    ついでに、ブラシの破棄を using ブロックで行うように、
     
    Code Snippet
     
    using (Brush mySolidBrush = new SolidBrush(Color.FromArgb(255, 1, 1))
    {
      g.FillRectangle(mySolidBrush, 10, 10, 10, 10);
    }

     

     

     
    などとすると良いかもしれません。
     
    2008年11月4日 13:47
  • あまり時間が取れないので簡潔にだけ。

     

    System.Windows.Media名前空間に属するクラス群は.NET Framework 3.0以降のクラスです。

    Visual Studio 2005からも使えなくはないですが、標準では使用できません。

     

    http://msdn.microsoft.com/ja-jp/library/system.windows.media.solidcolorbrush(VS.85).aspx

    バージョン情報
    .NET Framework
    サポート対象 : 3.0

     

    Visual Studio 2005は基本的に.NET Framework 2.0向けです。

    参照設定を追加する等を行えば、3.0のクラスも使えますという認識でいてください。

     

    また、System.Windows.Media名前空間のクラスとSystem.Drawing名前空間のクラスは基本的に別々と思ってください。

    Graphicsに対して通常、SolidColorBrushは使いません。

    名前が似ているSystem.Drawing.SolidBrushを使って下さい。

     

    http://msdn.microsoft.com/ja-jp/library/system.drawing.solidbrush(VS.80).aspx

    2008年11月4日 14:33
    モデレータ
  • 内容が被ってしまったので追記しておきます。

     

    System.Windows.Media名前空間に含まれるクラス群は.NET Framework 3.0で追加されたものですが、.NET Framework 3.0はWindows 2000にインストールできません。

    Windows 2000に対応する必要があるのであれば、System.Windows.Media名前空間のクラス群は使えないと思ってください。

    2008年11月4日 14:59
    モデレータ
  •  

    K.Takaokaさん、Azuleanさん、適切なご指摘本当に有難うございます。疑問が余すところなく氷解しました。

    心から感謝申し上げます。

    2008年11月5日 10:01
  • Code Snippet

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.IO;
    using System.Runtime.Serialization.Formatters.Binary;

     

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

            private void Form1_Load(object sender, EventArgs e)
            {
               Image initialImage;
                System.Reflection.Assembly myAssembly = System.Reflection.Assembly.GetExecutingAssembly();
              
                initialImage = new Bitmap(myAssembly.GetManifestResourceStream("testTransparentAppli.tMap.png"));

                using (Graphics g = Graphics.FromImage(initialImage))
                {
                    using (SolidBrush mySolidBrush = new SolidBrush(Color.FromArgb(255, 1, 1)))
                    {
                        g.FillRectangle(mySolidBrush, 10, 10, 10, 10);
                        ((Bitmap)initialImage).MakeTransparent(Color.FromArgb(255, 1, 1));
                        ((Image)initialImage).Save("partiallyTransparent.png");
                    }
                }

            }
        }
    }

     

     

    自分の前出のコードでは通らないところがあったので、成功したものを載せさせていただきます。

    2008年11月5日 12:40
  • こんばんは!(^^)!ふ~です。

     

    実際に透明色を付加して見ますと、一度、ファイルに書込み、再度読み込んでからMakeTransparent()を使用すると透明色のファイルが出来ました。すこし、コツがあるようです。

     

    VisualStudio2008 手順をまとめて見ました。
    ◆「Resources」フォルダーを作成する
    1.ソリューションエクスプローラでプロジェクト名をマウス選択しプロパティを開く
    2.「リソース」を選択する
    3.文字列ー>イメージを選択する。
    4.リソースを追加するを選択する。(ここまで来ると「Resources」ディレクトリが作られる)
    5.既存のPngファイルを追加したいので途中で止める。

    ◆リソースファイルを追加する
    1.ソリューションエクスプローラにある
    2.「Resources」フォルダーの中へ既存のPngファイルをドラッグ&ドロップする。
    3.そのファイルのプロパティを開き「ビルドアクション」を「埋め込まれたリソース」に設定する。

    ◆透明色を加えられたPngファイルの位置(実行プログラムのある場所)
    1.F:\Documents and Settings\Administrator\My Documents\Visual Studio 2008\
                            Projects\Project1\WinTransparent\WinTransparent\bin\Debug
       

    <Form1.csのソース> 

    using System;
    using System.Drawing;
    using System.Windows.Forms;
    using System.IO;
    using System.Reflection;
    using System.Diagnostics;

    namespace WinTransparent
    {
     public partial class Form1 : Form
     {
      Bitmap initialBitmap;
      string strFileName = "tran.png";  // 透明色を試験する絵のファイル名 (ここを変更します)

      public Form1()
      {
       InitializeComponent();
       pictureBox1.Paint += new PaintEventHandler(pictureBox1_Paint);
      }

      void pictureBox1_Paint(object sender, PaintEventArgs e)
      {
       e.Graphics.DrawImage(initialBitmap, new PointF(0.0F, 0.0F));
      }

      private void Form1_Load(object sender, EventArgs e)
      {
       Assembly _assembly;
       Stream _imageStream=null;
       
       try
       {
        _assembly = Assembly.GetExecutingAssembly();

        //このアセンブリの全てのリソース名を取得する
        string[] resources = _assembly.GetManifestResourceNames();
     
        //リソース名を一つずつ表示する
        foreach (string resource in resources)
         Debug.WriteLine(resource);

        _imageStream = _assembly.GetManifestResourceStream("WinTransparent.Resources." + strFileName );
       }
       catch
       {
        MessageBox.Show("リソースアクセスエラーが発生した。");
       }

       Bitmap tmpBitmap = new Bitmap(_imageStream);

       using (Graphics g = Graphics.FromImage(tmpBitmap))
       {
        // 白ブラシを作成する
        SolidBrush mySolidBrush = new SolidBrush(Color.FromArgb(255, 255, 255));

        // 表示位置
        RectangleF recSize = g.VisibleClipBounds;
     
        // 絵の一部を白で塗り潰す。
        g.FillRectangle(mySolidBrush, recSize.Left + (recSize.Width / 4),
         recSize.Top + (recSize.Height / 4), (recSize.Width / 2), (recSize.Height / 2));

     

        // 一度ファイルに保存する。
        tmpBitmap.Save(strFileName);
       }

       // このビットマップを解放する。
       tmpBitmap.Dispose();
      
       // ファイルに保存した白で一部を塗り潰した絵を読込む    
       initialBitmap = new Bitmap(strFileName);

       // 白い部分を透明色にする。
       initialBitmap.MakeTransparent(Color.FromArgb(255, 255, 255));

       // 透明色のファイルを保存する。
       initialBitmap.Save(strFileName);
      }
     }
    }

    以上 ご参考になれば幸いです。

    2008年11月8日 18:04
  • なんとなく気がついたので少しだけフォローしておきます
     

    > 実際に透明色を付加して見ますと、一度、ファイルに書込み、再度読み込んでから

    > MakeTransparent()を使用すると透明色のファイルが出来ました。すこし、コツがあるようです。

     

    そんなことはないと思うのですが、確認方法などに問題があったりしませんか?

     

    たとえば、Bitmap クラスで扱っている限りでは「透明」の部分に「色」がもてます。つまり「透明な赤」と「透明な白」という2つの透明色を表現することができます。このような状態で透明度をサポートしないような描画方法を用いたり、「透明な赤」と「透明な白」を理解して赤や白で表示してくれるビュワーなどを使ってしまうと、透明色になっていることを目で確認しにくいような場合があります。

     

    このような状態の透明を持つものをファイルに保存すると、そのファイルがサポートする範囲にデータが失われます。どのような情報が失われてしまうのかは保存したファイルフォーマットに依存しますが、その結果として人間の目で確認しやすい状態になったのではないかと思います。

    (示されているコードでは、ファイルにかきまないで透明化する処理がどのようなものだったかは想像できないのですけど)

     

    > VisualStudio2008 手順をまとめて見ました。

    ここで書かれていることは、すこしやってることがちぐはぐになっているように思います。

    リソースマネージャによって管理されている画像(アセンブリリソース)と、埋め込みリソースとして管理されている画像は、.NET のランタイムからみてまったく異なるものですので同列に扱えるものではありません。

    手順の前半ではアセンブリリソースに画像を追加するような操作を行い、最終的に埋め込みリソースとするのは状態としておかしいと思います。

     

     

    アセンブリリソースとして既存の画像を追加する場合、[リソースの追加] のプルダウンメニューから [既存のファイルの追加] で追加することができます。多くの場合は、拡張子などから自動的にファイル形式を判断してイメージリソースとして取り込まれます。アセンブリリソースとして参照されている場合、対象のファイルは .resx ファイルに実体が取り込まれるため、ソリューションエクスプローラーなどでファイルのプロパティを開くとビルドアクションは「なし」になっているのが通常の状態です。

     

    これに対して、ビルドアクションを「埋め込まれたリソース」とすると、そのファイルはアセンブリリソースではなく埋め込みリソースとなります。埋め込みリソースは特に Resouces フォルダにファイルを置く必要はありません(Resouces フォルダにファイルを置いて問題になることもありません)が、こちらはアセンブリリソースと比較すると単純なストリームとしての提供となるため、かなり原始的な手法になります。

     

    コンポーネント開発や ASP.NET 用の Web ライブラリ開発など、一部の機能ではアセンブリリソースではなく埋め込みリソースとして画像や JavaScript などを埋め込むことが必須となる用件もありますが、そのような特別な理由がないかぎりアプリケーションにはアセンブリリソースとして埋め込むのが Visual Studio の基本スタンスのようです。経験的にも、データ管理や機能的な面も考慮しても、埋め込みリソースはアプリケーションの外部要件にかからないかぎり使わないほうがよいのではと思います。

    2008年11月27日 14:38
  • こんばんは!(^^)!ふ~です。

     

    私の行動パターンは、ソースを見て、動作を予想する。更に、可能であれば実際に汗水たらして実験すること、予想した理論が正しいことを確認しようと努力する過程で、もっと深い意外な知識が手に入るのが楽しみで生きています。

    C#が業界トップになるように、プログラマーの栄養源になる明快で良いサンプルが特効薬と思ってます。

     

     

     

     

    2008年11月27日 17:03