2012-08-07 22 views
15

मैं ग्राफिक्स को कैनवास पर पेंट करना चाहता हूं जैसे कि रंग additive हैं। उदाहरण के लिए, मैं इस का उत्पादन करना चाहते हैं:
Proper additive colorsअल्फा के साथ कैसे पेंट करें?

लेकिन बजाय, मैं इस मिल:
My results

ध्यान दें कि आधा सफेद, आधा काले रंग की पृष्ठभूमि जानबूझकर है, बस देखने के लिए कैसे अल्फा दोनों के साथ सूचना का आदान प्रदान पृष्ठभूमि। मैं इस काम को पृष्ठभूमि के साथ खुश कर दूंगा। यहाँ मेरी कोड है:

public class VennColorsActivity extends Activity { 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     class VennView extends View { 
      public VennView(Context context) { 
       super(context); 
      } 

      @Override 
      protected void onDraw(Canvas canvas) { 
       super.onDraw(canvas); 
       int alpha = 60, val = 255; 
       int ar = Color.argb(alpha, val, 0, 0); 
       int ag = Color.argb(alpha, 0, val, 0); 
       int ab = Color.argb(alpha, 0, 0, val); 
       float w = canvas.getWidth(); 
       float h = canvas.getHeight(); 
       float cx = w/2f; 
       float cy = h/2; 
       float r = w/5; 
       float tx = (float) (r * Math.cos(30 * Math.PI/180)); 
       float ty = (float) (r * Math.sin(30 * Math.PI/180)); 
       float expand = 1.5f; 
       Paint paint = new Paint(); 
       paint.setColor(Color.WHITE); 
       canvas.drawRect(new Rect(0, 0, (int) w, (int) (h/2)), paint); 
       PorterDuff.Mode mode = android.graphics.PorterDuff.Mode.ADD; 
       paint = new Paint(Paint.ANTI_ALIAS_FLAG); 
       paint.setColorFilter(new PorterDuffColorFilter(ar, mode)); 
       paint.setColor(ar); 
       canvas.drawCircle(cx, cy - r, expand * r, paint); 
       paint.setColorFilter(new PorterDuffColorFilter(ag, mode)); 
       paint.setColor(ag); 
       canvas.drawCircle(cx - tx, cy + ty, expand * r, paint); 
       paint.setColorFilter(new PorterDuffColorFilter(ab, mode)); 
       paint.setColor(ab); 
       canvas.drawCircle(cx + tx, cy + ty, expand * r, paint); 
      } 
     } 
     this.setContentView(new VennView(this)); 
    } 
} 

किसी की मदद कृपया मुझे समझ कैसे एंड्रॉयड ग्राफिक्स में additive रंग के साथ पेंट करने के लिए?

उत्तर

26

आप सही रास्ते पर हैं। वहाँ अपने कोड में 3 प्रमुख मुद्दे हैं:

  • आप अपनी छवि प्रतिपादन के लिए
  • उपयोग अस्थायी बिटमैप xfer स्थापित करने के लिए मोड आईएसओ रंग फिल्टर की आवश्यकता
  • अल्फा आदेश परिणाम आप देख रहे हैं प्राप्त करने के लिए 0xFF होना चाहिए

यहाँ है कि मैं क्या मोड xfer का उपयोग करके मिल गया है है। मैं क्या कर रहा हूं - सब कुछ अस्थायी बिटमैप में खींच रहा है और फिर पूरे कैनवास में पूरे बिटमैप को प्रस्तुत कर रहा है।

xfer mode rules

आप पूछ क्यों आप अस्थायी बिटमैप की ज़रूरत है? अच्छा प्रश्न! यदि आप मुख्य कैनवास पर सबकुछ खींच रहे हैं, तो आपके रंग मुख्य कैनवास पृष्ठभूमि रंग के साथ मिश्रित होंगे, इसलिए सभी रंग गड़बड़ हो जाएंगे। पारदर्शी अस्थायी बिटमैप आपके रंगों को यूआई

कृपया सुनिश्चित करें कि आप onDraw() में कुछ भी आवंटित नहीं कर रहे हैं - आप इस तरह से स्मृति को जल्द ही चलाएंगे .. यह भी सुनिश्चित करें कि आपने अपने अस्थायी बिटमैप को पुनर्नवीनीकरण किया है जब आपको इसकी आवश्यकता नहीं है।

package com.example.stack2; 

import android.app.Activity; 
import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.Bitmap.Config; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.graphics.PorterDuff.Mode; 
import android.graphics.PorterDuffXfermode; 
import android.os.Bundle; 
import android.view.View; 

public class YouAreWelcome extends Activity { 

    Bitmap tempBmp = Bitmap.createBitmap(1, 1, Config.ARGB_8888); 
    Canvas c = new Canvas(); 
    Paint paint = new Paint(); 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     class VennView extends View { 
      public VennView(Context context) { 
       super(context); 

      } 

      protected void onDraw(Canvas canvas) { 
       super.onDraw(canvas); 
       if(tempBmp.isRecycled() || tempBmp.getWidth()!=canvas.getWidth() || tempBmp.getHeight()!=canvas.getHeight()) 
       { 
        tempBmp.recycle(); 
        tempBmp = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), Config.ARGB_8888); 
        c.setBitmap(tempBmp); 
       } 

        //clear previous drawings 
       c.drawColor(Color.TRANSPARENT, Mode.CLEAR); 

       int alpha = 255, val = 255; 
       int ar = Color.argb(alpha, val, 0, 0); 
       int ag = Color.argb(alpha, 0, val, 0); 
       int ab = Color.argb(alpha, 0, 0, val); 
       float w = canvas.getWidth(); 
       float h = canvas.getHeight(); 
       float cx = w/2f; 
       float cy = h/2; 
       float r = w/5; 
       float tx = (float) (r * Math.cos(30 * Math.PI/180)); 
       float ty = (float) (r * Math.sin(30 * Math.PI/180)); 
       float expand = 1.5f; 
       paint.setAntiAlias(true); 
       paint.setXfermode(new PorterDuffXfermode(Mode.ADD)); 
       paint.setColor(ar); 
       c.drawCircle(cx, cy - r, expand * r, paint); 
       paint.setColor(ag); 
       c.drawCircle(cx - tx, cy + ty, expand * r, paint); 
       paint.setColor(ab); 
       c.drawCircle(cx + tx, cy + ty, expand * r, paint); 
       canvas.drawBitmap(tempBmp, 0, 0, null); 
      } 
     } 
     this.setContentView(new VennView(this)); 
    } 
} 
+1

धन्यवाद बहुत, पावेल; और बहुत जल्दी भी! –

+3

बीटीडब्ल्यू, क्या आप पोर्टरडफ.मोड.एडीडी के विकल्प के बारे में जानेंगे जो एसडीके संस्करण 8 के साथ संगत है? दस्तावेज कहता है कि एडीडी संस्करण 8 में जोड़ा गया था लेकिन यह झूठ है। यह वास्तव में संस्करण 11 में पेश किया गया था और कुछ पुराने उपकरणों पर क्रैश किया गया था जिन्हें मेरे विजेट को स्थापित करने की अनुमति नहीं दी जानी चाहिए। –

+1

यह बहुत अच्छा है!क्या आप इस तकनीक को बिटमैप्स पर लागू कर सकते हैं जो एक-दूसरे को ओवरलैप करते हैं? –

2

धन्यवाद फिर से पावेल। मेरे लिए यह पता लगाना बहुत मुश्किल होता। मैं विवरण में बेहतर ड्रिल करने के लिए अपने स्वयं के प्रश्न का उत्तर दे रहा हूं, लेकिन मैंने आपका सबसे अच्छा जवाब स्वीकार कर लिया है।

आप सही हैं कि मैं ऑफ-स्क्रीन बिटमैप (और कैनवास) को बनाना और प्रबंधित करना नहीं चाहता हूं। यह अनिवार्य रूप से क्यों है कि मैंने यह उल्लेख किया कि इस काम को करने के लिए एक काला या सफेद पृष्ठभूमि ठीक होगी।

मैं प्रदर्शन के साथ कभी नहीं चिंतित हूँ इससे पहले कि मैं कुछ काम करते हुए देखना, लेकिन मैं उस बिंदु के बाद अपने सावधानी साझा करें। इसे ठीक करने के लिए अपने संस्करण को संपादित करना और उन सदस्यों को हटा देना नीचे कार्यान्वयन देता है।

इस मजबूत है? Canvas.drawColor() को दो कॉलों पर ध्यान दें जो मुझे संदेह है कि एक को भी जोड़ा जा सकता है।

package com.superliminal.android.test.venn; 

import android.app.Activity; 
import android.content.Context; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.graphics.PorterDuff.Mode; 
import android.graphics.PorterDuffXfermode; 
import android.os.Bundle; 
import android.view.View; 

public class VennColorsActivity extends Activity { 
    private Paint paint = new Paint(); 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     class VennView extends View { 
      public VennView(Context context) { 
       super(context); 
      } 

      @Override 
      protected void onDraw(Canvas canvas) { 
       super.onDraw(canvas); 
       canvas.drawColor(Color.BLACK); 
       canvas.drawColor(Color.TRANSPARENT, Mode.CLEAR); 
       int alpha = 255, val = 255; 
       int ar = Color.argb(alpha, val, 0, 0); 
       int ag = Color.argb(alpha, 0, val, 0); 
       int ab = Color.argb(alpha, 0, 0, val); 
       float w = canvas.getWidth(); 
       float h = canvas.getHeight(); 
       float cx = w/2f; 
       float cy = h/2; 
       float r = w/5; 
       float tx = (float) (r * Math.cos(30 * Math.PI/180)); 
       float ty = (float) (r * Math.sin(30 * Math.PI/180)); 
       float expand = 1.5f; 
       paint.setAntiAlias(true); 
       paint.setXfermode(new PorterDuffXfermode(Mode.ADD)); 
       paint.setColor(ar); 
       canvas.drawCircle(cx, cy - r, expand * r, paint); 
       paint.setColor(ag); 
       canvas.drawCircle(cx - tx, cy + ty, expand * r, paint); 
       paint.setColor(ab); 
       canvas.drawCircle(cx + tx, cy + ty, expand * r, paint); 
      } 
     } 
     setContentView(new VennView(this)); 
    } 
} 
+1

यह समाधान भी सही है। मैंने अलग बिटमैप का उपयोग करने का सुझाव दिया क्योंकि आमतौर पर आप केवल उन रंगों को मिश्रित करना चाहते हैं जिन्हें आप चाहते हैं और बाकी यूआई के साथ गड़बड़ नहीं करते हैं। आपके कोड पर केवल एक ही टिप्पणी यह ​​है कि 'canvas.drawColor (color.black);' कॉल बेकार है क्योंकि आप 'canvas.drawColor (Color.TRANSPARENT, Mode.CLEAR) को कॉल करके पूरे क्षेत्र को साफ़ करते हैं; '। तो सिद्धांत में आप इस लाइन को –

+0

@ मलिंडा ग्रीन ड्रॉप कर सकते हैं मैं प्रत्येक गतिविधि पर कैनवास के पेंट रंग को कैसे बदल सकता हूं, मेरी गतिविधि में क्लिक करें ताकि यह अलग पृष्ठभूमि रंग दे सके – Erum

+0

@Erum हनान बस बटन के ऑनक्लिक विधि और सेट में एक रंग संग्रहीत करें उस रंग के साथ canvas.drawColor के साथ पृष्ठभूमि के रूप में रंग। –

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