0

これは簡単なはずですが、それを行う方法が見つからないようです。カスタム描画を行うオーバーライドされたペイント メソッドを持つカスタム WinForms コントロールがあります。

メモリにビットマップがあり、HashBrush で全体をペイントするだけで、ビットマップの透明な部分がペイントされないようにアルファ チャネルを保持します。

メモリ内のビットマップは単純な形状ではないため、一連のパスなどとして定義することはできません。

編集: コードの表示に応じて、ペイント ルーチンには多くのコードがあるため、問題のメソッドである関連するスニペットのみを含めています。このメソッドは、メイン ペイント オーバーライドから呼び出されます。黒の透明マスクである画像のリストを受け取り、それらを 1 つに結合します。次に、ColorMatrix を使用して、作成した結合画像の色を変更し、背景の上に重ねることができるようにします。私が達成したいのは、その上にハッシュマークもペイントできるようにすることだけです。

    private void PaintSurface(PaintEventArgs e, Image imgParent, List<Image> surfImgs, Rectangle destRect, ToothSurfaceMaterial material)
    {
        using (Bitmap bmp = new Bitmap(imgParent.Width, imgParent.Height,
                       System.Drawing.Imaging.PixelFormat.Format32bppPArgb))
        {

            using (Graphics g = Graphics.FromImage(bmp))
            {
                foreach (Image img in surfImgs)
                {
                    g.DrawImage(img, System.Drawing.Point.Empty);
                }
            }

            ColorMatrix matrix = new ColorMatrix(
                new float[][] {
                    new float[] { 0, 0, 0, 0, 0},
                    new float[] { 0, 0, 0, 0, 0},
                    new float[] { 0, 0, 0, 0, 0},
                    new float[] { 0, 0, 0, 0.7f, 0},
                    new float[] { material.R / 255.0f,
                                  material.G / 255.0f,
                                  material.B / 255.0f,
                                  0, 1}
                  });

            ImageAttributes imageAttr = new ImageAttributes();
            imageAttr.SetColorMatrix(matrix);

            Rectangle r = GetSizedRect(imgParent, destRect);
            e.Graphics.DrawImage(bmp,
                                 r,
                                 0,
                                 0,
                                 bmp.Width,
                                 bmp.Height,
                                 GraphicsUnit.Pixel, imageAttr);
        }
    }
4

2 に答える 2

0

overkillColorMatrixは必要ないと思います。必要なのは だけです。これは、要件に合わない可能性がありますが、アイデアを提供するコードです。これは、私があなたの問題をよく理解していない可能性があるためです。問題がある場合は、コメントを残してください。答えを改善しようとします。ColorMap

ImageAttributes imgA = new ImageAttributes();
ColorMap cm = new ColorMap();
cm.OldColor = Color.Black
cm.NewColor = Color.FromArgb((byte)(0.7*255), Color.Green);
imgA.SetRemapTable(new ColorMap[] {cm });         
GraphicsUnit gu = GraphicsUnit.Pixel;   
g.DrawImage(imageToDraw,new Point[]{Point.Empty, 
                                    new Point(backImage.Width/2,0), 
                                    new Point(0,backImage.Height/2)},
                        Rectangle.Round(imageToDraw.GetBounds(ref gu)), 
                        GraphicsUnit.Pixel, imgA);

これは、目的の Rectangle を見つけるために使用されるnew Point[]3 つの配列です。Points上記のコードは、 の上にを描画しimageToDrawbackImageBlack、 の色を のGreen色に変換して変換するために使用されOpacity = 70%ます。それがあなたのコードを実現したいものです。

アップデート

これはあなたが望むものかもしれません。実際、あなたのコードはあなたが望むものを示していません。あなたの問題に関連するものを何も実装していないものを示しているだけです。これは、質問の最初の説明から推測できます。入力は、背景色 (後で部分的に透明になります) の画像Blackです。必要な出力は、黒以外のすべての領域がHatchBrush. Blackこの出力は、背景を背景に変えるために処理されpartially transparentます。

public void PaintHatchBrush(Bitmap input, HatchBrush brush){
   using(Graphics g = Graphics.FromImage(input)){
      g.Clip = GetForegroundRegion(input, Color.Black);
      GraphicsUnit gu = GraphicsUnit.Pixel;
      g.FillRectangle(brush, input.GetBounds(ref gu));
   }
}
//This is implemented using `GetPixel` which is not fast, but it gives you the idea.
public Region GetForegroundRegion(Bitmap input, Color backColor){
  GraphicsPath gp = new GraphicsPath();
      Rectangle rect = Rectangle.Empty;          
      bool jumpedIn = false;
      for (int i = 0; i < bm.Height; i++) {
          for (int j = 0; j < bm.Width; j++) {
             Color c = bm.GetPixel(j, i);
             if (c != backColor&&!jumpedIn) {
                 rect = new Rectangle(j, i, 1, 1);                        
                 jumpedIn = true;
             }
             if (jumpedIn && (c == backColor || j == bm.Width - 1)) {
                 rect.Width = j - rect.Left;
                 gp.AddRectangle(rect);
                 jumpedIn = false;
             }
          }
      }
      return new Region(gp);
}
//Usage
HatchBrush brush = new HatchBrush(HatchStyle.Percent30, Color.Green, Color.Yellow);
PaintHatchBrush(yourImage, brush);
//then yourImage will have HatchBrush painted on the surface leaving the Black background intact.
//This image will be used in the next process to turn the Black background into 70%
//opacity background as you did using ColorMatrix (or more simply using ColorMap as I posted previously)
于 2013-10-18T17:32:47.583 に答える