2012-04-26 13 views
10

अवलोकनपारदर्शिता और अस्पष्टता के साथ कैनवास पर पेंट कैसे करें?

GR32 लाइब्रेरी से, मैं एक ग्रिड जो इतनी तरह मेरे पारदर्शी पृष्ठभूमि हो जाएगा प्रस्तुत करना TImgView32 उपयोग कर रहा हूँ:

enter image description here

TImgView32 मैं एक नियमित TImage है अंदर रखा, जहाँ मैं कैनवास पर ड्राइंग किया जाएगा, कुछ इस तरह:

enter image description here

कार्य

मैं जो हासिल करना चाहता हूं वह ब्रश की अस्पष्टता सेट करने की क्षमता है, जिससे मेरे प्रोग्राम में छवि संपादन के लिए और संभावनाएं मिलती हैं। एक फ्लैट रंग तैयार करने के बजाय, ब्रश की अस्पष्टता सेट करने से रंग गहराई आदि के विभिन्न स्तरों की अनुमति मिलती है।

मुझे इस प्रश्न को पहले खोजते समय मिला: Draw opacity ellipse in Delphi 2010 - एंड्रियास रेजब्रांड ने इसके जवाब में कुछ उदाहरण दिए हैं सवाल।

मैंने देखा है कि एंड्रियास ने क्या किया, और अपने स्वयं के सरलीकृत प्रयास के साथ आया लेकिन मैं एक समस्या से फंस गया हूं। इन अगले दो छवियों पर एक नजर डालें, पहली समस्या अधिक दिखाने के लिए पारदर्शी पृष्ठभूमि और एक काले रंग की पृष्ठभूमि के साथ दूसरे के साथ है स्पष्ट:

enter image description here enter image description here

आप ब्रश के आसपास, देख सकते हैं (सर्कल) एक बहुत ही कष्टप्रद वर्ग है जिसे मैं छुटकारा नहीं पा सकता हूं। जो दिखाना चाहिए वह ब्रश है।

procedure DrawOpacityBrush(ACanvasBitmap: TBitmap; X, Y: Integer; 
    AColor: TColor; ASize: Integer; Opacity: Integer); 
var 
    Bmp: TBitmap; 
begin 
    Bmp := TBitmap.Create; 
    try 
    Bmp.SetSize(ASize, ASize); 
    Bmp.Transparent := False; 

    with Bmp.Canvas do 
    begin 
     Pen.Color := AColor; 
     Pen.Style := psSolid; 
     Pen.Width := ASize; 
     MoveTo(ASize div 2, ASize div 2); 
     LineTo(ASize div 2, ASize div 2); 
    end; 

    ACanvasBitmap.Canvas.Draw(X, Y, Bmp, Opacity); 
    finally 
    Bmp.Free; 
    end; 
end; 

procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton; 
    Shift: TShiftState; X, Y: Integer); 
begin 
    DrawOpacityBrush(Image1.Picture.Bitmap, X, Y, clRed, 50, 85); 
end; 

जो एक नियमित रूप से बिटमैप पर इस का उत्पादन: यह मेरी उन परिणामों का उत्पादन किया जाता है कोड

enter image description here

विचार मैं (अस्पष्टता के साथ एक अंडाकार बनाने के एंड्रियास रास्ता के आधार पर) था कैनवास पर एक विशिष्ट ब्रश प्रस्तुत करना था, इसे ऑफस्क्रीन बिटमैप पर असाइन करें, फिर इसे अस्पष्टता के साथ मुख्य बिटमैप पर दोबारा हटा दें। किनारे के चारों ओर कष्टप्रद वर्ग को छोड़कर, कौन सा काम करता है।

स्क्रीनशॉट में दिखाए गए अस्पष्टता वाले ब्रश को मैं कैसे प्रस्तुत कर सकता हूं, लेकिन ब्रश सर्कल के चारों ओर उस वर्ग के बिना?

यदि मैं Bmp.Transparent := True सेट करता हूं तो अभी भी एक सफेद बॉक्स है, लेकिन अब कोई अस्पष्टता नहीं है। बस एक ठोस सफेद वर्ग और ठोस भरा लाल सर्कल।

उत्तर

13

TCanvas.Draw() की अस्पष्टता सुविधा आप जो करने का प्रयास कर रहे हैं उसका समर्थन नहीं करती है, कम से कम जिस तरह से आप इसे उपयोग करने का प्रयास नहीं कर रहे हैं। जिस प्रभाव को आप चाहते हैं उसे पूरा करने के लिए, आपको 32-बिट TBitmap बनाने की आवश्यकता है ताकि आपके पास प्रति-पिक्सेल अल्फा चैनल हो, फिर प्रत्येक पिक्सेल के लिए अल्फा भरें, अल्फा को 0 पिक्सल के लिए सेट करें, जिसे आप नहीं चाहते हैं, और सेटिंग पिक्सेल के लिए वांछित अस्पष्टता के लिए अल्फा जो आप चाहते हैं। फिर, TCanvas.Draw() पर कॉल करते समय, प्रति अस्पष्टता का उपयोग करने के लिए इसे कहने के लिए इसकी अस्पष्टता 255 पर सेट करें।

procedure DrawOpacityBrush(ACanvas: TCanvas; X, Y: Integer; AColor: TColor; ASize: Integer; Opacity: Byte); 
var 
    Bmp: TBitmap; 
    I, J: Integer; 
    Pixels: PRGBQuad; 
    ColorRgb: Integer; 
    ColorR, ColorG, ColorB: Byte; 
begin 
    Bmp := TBitmap.Create; 
    try 
    Bmp.PixelFormat := pf32Bit; // needed for an alpha channel 
    Bmp.SetSize(ASize, ASize); 

    with Bmp.Canvas do 
    begin 
     Brush.Color := clFuchsia; // background color to mask out 
     ColorRgb := ColorToRGB(Brush.Color); 
     FillRect(Rect(0, 0, ASize, ASize)); 
     Pen.Color := AColor; 
     Pen.Style := psSolid; 
     Pen.Width := ASize; 
     MoveTo(ASize div 2, ASize div 2); 
     LineTo(ASize div 2, ASize div 2); 
    end; 

    ColorR := GetRValue(ColorRgb); 
    ColorG := GetGValue(ColorRgb); 
    ColorB := GetBValue(ColorRgb); 

    for I := 0 to Bmp.Height-1 do 
    begin 
     Pixels := PRGBQuad(Bmp.ScanLine[I]); 
     for J := 0 to Bmp.Width-1 do 
     begin 
     with Pixels^ do 
     begin 
      if (rgbRed = ColorR) and (rgbGreen = ColorG) and (rgbBlue = ColorB) then 
      rgbReserved := 0 
      else 
      rgbReserved := Opacity; 
      // must pre-multiply the pixel with its alpha channel before drawing 
      rgbRed := (rgbRed * rgbReserved) div $FF; 
      rgbGreen := (rgbGreen * rgbReserved) div $FF; 
      rgbBlue := (rgbBlue * rgbReserved) div $FF; 
     end; 
     Inc(Pixels); 
     end; 
    end; 

    ACanvas.Draw(X, Y, Bmp, 255); 
    finally 
    Bmp.Free; 
    end; 
end; 

procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton; 
    Shift: TShiftState; X, Y: Integer); 
begin 
    DrawOpacityBrush(Image1.Picture.Bitmap.Canvas, X, Y, clRed, 50, 85); 
end; 
+0

ग्रेट उत्तर धन्यवाद रेमी।मुझे पता था कि मेरे बिटमैप्स पीएफ 24 बिट थे, लेकिन इसे पीएफ 32 बिट पर सेट करने या नहीं समझने के बारे में पता था। मैं शायद अपनी पृष्ठभूमि को गलत तरीके से मिटा रहा हूं, क्योंकि मैं फिक्स्डेंसी रंग को निश्चित रूप से सेट कर रहा हूं और जब मैं मिटा देता हूं तो clbtnFace के मान को सेट कर रहा हूं। –

+1

आप इस वर्ग को भी उपयोगी पाते हैं: http://code.google.com/p/transparent-canvas/। यह 32-बिट, प्रति-पिक्सेल-अल्फा ड्राइंग के आसपास एक रैपर है जो टीसीएनवास के समान इंटरफ़ेस के साथ है। एक बनाएं, इसे आकर्षित करें, फिर इसे कैनवास पर खींचा जाए। एमपीएल लाइसेंस प्राप्त है ताकि आप इसे कहीं भी इस्तेमाल कर सकें। –

संबंधित मुद्दे