Android, कैनवास: मैं एक सतह दृश्य में रहने वाले कैनवास (= बिटमैप्स) की सामग्री कैसे मिटाऊं?


92

एक साधारण खेल बनाने के लिए, मैंने एक टेम्पलेट का उपयोग किया जो कि इस तरह से बिटमैप के साथ एक कैनवास खींचता है:

private void doDraw(Canvas canvas) {
    for (int i=0;i<8;i++)
        for (int j=0;j<9;j++)
            for (int k=0;k<7;k++)   {
    canvas.drawBitmap(mBits[allBits[i][j][k]], i*50 -k*7, j*50 -k*7, null); } }

(कैनवास को "रन ()" / सरफेस व्यू में गेमट्रेड में रहने के लिए परिभाषित किया गया है।)

मेरा पहला सवाल यह है कि मैं एक नए लेआउट के लिए पूरे कैनवास को कैसे (या रिड्रा) स्पष्ट करूं ?
दूसरा, मैं स्क्रीन के एक हिस्से को कैसे अपडेट कर सकता हूं?

// This is the routine that calls "doDraw":
public void run() {
    while (mRun) {
        Canvas c = null;
        try {
            c = mSurfaceHolder.lockCanvas(null);
            synchronized (mSurfaceHolder) {
                if (mMode == STATE_RUNNING) 
                    updateGame();
                doDraw(c);          }
        } finally {
            if (c != null) {
                mSurfaceHolder.unlockCanvasAndPost(c);  }   }   }       }

जवाबों:


77

मैं एक नए लेआउट (= खेल में कोशिश) के लिए WHOLE कैनवास को कैसे (या रिड्रा) स्पष्ट करूं?

बस कॉल करें Canvas.drawColor(Color.BLACK), या जो भी रंग आप के Canvasसाथ साफ़ करना चाहते हैं ।

और: मैं स्क्रीन के एक हिस्से को कैसे अपडेट कर सकता हूं?

ऐसी कोई विधि नहीं है जो एंड्रॉइड ओएस के स्क्रीन को अपडेट करते समय केवल "स्क्रीन के एक हिस्से" को अपडेट करती है। लेकिन, जब आप अपने पर पुरानी ड्राइंग को साफ़ नहीं कर रहे हैंCanvas , तो पुराने चित्र अभी भी सतह पर हैं और यह शायद स्क्रीन के "सिर्फ एक हिस्से को अपडेट" करने का एक तरीका है।

इसलिए, यदि आप "स्क्रीन के एक हिस्से को अपडेट करना चाहते हैं", तो कॉलिंग Canvas.drawColor()विधि से बचें ।


4
नहीं, यदि आप सतह के प्रत्येक पिक्सेल को नहीं खींचते हैं तो आपको बहुत ही अजीब परिणाम मिलेंगे (क्योंकि स्वैपिंग पॉइंटर्स द्वारा डबल बफ़रिंग प्राप्त की जाती है, इसलिए उन हिस्सों में जहाँ आप ड्राइंग नहीं कर रहे हैं, आप यह नहीं देखेंगे कि पहले क्या था)। आप है प्रत्येक यात्रा पर सतह के हर पिक्सेल पुनः बनाने का।
गुइलुम ब्रूनरी

2
@Viktor Lannér: यदि आप कॉल करते हैं mSurfaceHolder.unlockCanvasAndPost(c)और फिर c = mSurfaceHolder.lockCanvas(null), तो नए cमें पहले जैसी चीज़ नहीं है c। आप किसी सरफेस व्यू के सिर्फ एक हिस्से को अपडेट नहीं कर सकते हैं, जो कि ओपी मुझसे पूछ रहा था।
गिलियूम ब्रूनरी

1
@ गिल्यूम ब्रूनरी: सच है, लेकिन सभी नहीं। जैसा कि मैंने लिखा था आप स्क्रीन के एक हिस्से को अपडेट नहीं कर सकते। लेकिन आप स्क्रीन पर पुरानी ड्राइंग रख सकते हैं, जिसका प्रभाव सिर्फ "स्क्रीन के एक हिस्से को अपडेट करना" होगा। अपने आप को एक नमूना आवेदन में आज़माएं। Canvasपुरानी ड्राइंग रखता है।
व्रोकलाई

2
मुझ पर शर्म की बात है !!! मैंने अपने एरे को केवल शुरुआती समय में खेल शुरू में ही चालू नहीं किया था - फिर सभी ओएलडी टुकड़े "ऑनस्क्रीन" बने रहे - वे नए सिरे से तैयार किए गए थे !!! मैं अपने "विनम्रता" के लिए बहुत अच्छा हूँ! तुम दोनों का धन्यवाद !!!
samClem

1
फिर यह शायद इसलिए है क्योंकि लाइव वॉलपेपर नियमित सरफेस व्यू के समान काम नहीं करते हैं। वैसे भी @samClem: हमेशा कैनवस के हर पिक्सेल को हर फ्रेम पर (जैसा कि डॉक्स में कहा गया है) या आपके पास अजीब टिमटिमाना होगा।
गुइलुम ब्रूनरी

278

पोर्टरडफ के साथ पारदर्शी रंग ड्रा करें स्पष्ट मोड जो मैं चाहता था उसके लिए चाल करता है।

Canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR)

2
यह काम करना चाहिए, लेकिन Bitmap#eraseColor(Color.TRANSPARENT)नीचे हेमैक के उत्तर में 4.4 (कम से कम N7.2) पर उपयोग किए जाने के कारण खराब प्रतीत होता है ।
nmr

3
वास्तव में, Color.TRANSPARENTअनावश्यक है। PorterDuff.Mode.CLEARएक ARGB_8888बिटमैप के लिए पूरी तरह से पर्याप्त है जिसका मतलब है कि अल्फा और रंग सेट करना [0, 0]। एक और तरीका है Color.TRANSPARENTजिसके साथ उपयोग करना है PorterDuff.Mode.SRC
जियासली

1
यह ट्रांसपेरेंट
पल्लव बोहरा

31

Google समूहों में यह पाया और यह मेरे लिए काम किया ..

Paint clearPaint = new Paint();
clearPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
canvas.drawRect(0, 0, width, height, clearPaint); 

यह बिटमैप सेट करते समय चित्र आयतों आदि को हटाता है।


4
यह मुझे एक काला क्षेत्र देता है - मेरे पीछे जो बिटमैप नहीं है :(
slott

यह ठीक है, लेकिन बिटमैप भी आपके कहे अनुसार हटा दिया जाता है।
उमर रहमान

में stackoverflow.com/questions/9691985/... कैसे कैनवास से कुछ आयत पर एक बिटमैप की एक आयत आकर्षित करने के लिए समझाया गया है। एक आयत में एक छवि बदलें इस प्रकार काम करता है: पिछली सामग्री को लीयर करें, नई छवि
मार्टिन

18

मैंने @ उत्तर देने का प्रयास किया:

canvas.drawColor(Color.TRANSPARENT, Mode.CLEAR);

लेकिन यह मेरे लिए काम नहीं करता है।

मेरे लिए, समाधान था:

canvas.drawColor(Color.TRANSPARENT, Mode.MULTIPLY);

शायद कुछ एक ही समस्या है।


4
पारदर्शिता के साथ गुणा करना उत्तर है। अन्यथा यह कुछ उपकरणों पर काले रंग का अंत कर सकता है।
एंड्रियास रुडोल्फ

16

पाथ क्लास के रीसेट विधि का उपयोग करें

Path.reset();

यह वास्तव में सबसे अच्छा जवाब है अगर आपका एक मार्ग का उपयोग कर रहा है। अन्य लोग ब्लैक स्क्रीन के साथ उपयोगकर्ता को छोड़ सकते हैं। धन्यवाद।
j2emanue

12
mBitmap.eraseColor(Color.TRANSPARENT);

canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);

2
यह सबसे सही कैसे है? जब आप सिर्फ ड्राकॉल कर सकते हैं तो बिटमैप का उपयोग क्यों करें?
रिची एचएच

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

क्या आप एक संपूर्ण कोड pls लिख सकते हैं?
डायनो क्राइस

4

कृपया सतह से नीचे का कोड पेस्ट करें क्लास कन्स्ट्रक्टर का विस्तार करें …………।

कंस्ट्रक्टर कोडिंग

    SurfaceHolder holder = getHolder();
    holder.addCallback(this);

    SurfaceView sur = (SurfaceView)findViewById(R.id.surfaceview);
    sur.setZOrderOnTop(true);    // necessary
    holder = sur.getHolder();
    holder.setFormat(PixelFormat.TRANSPARENT);

xml कोडिंग

    <com.welcome.panelview.PanelViewWelcomeScreen
        android:id="@+id/one"
        android:layout_width="600px"
        android:layout_height="312px"
        android:layout_gravity="center"
        android:layout_marginTop="10px"
        android:background="@drawable/welcome" />

कोड से ऊपर का प्रयास करें ...


holder.setFormat (PixelFormat.TRANSPARENT); इससे मेरा काम बनता है।
हारून ली

3

यहां एक न्यूनतम उदाहरण का कोड दिखाया गया है कि आपको हमेशा कैनवस के प्रत्येक पिक्सेल को प्रत्येक फ्रेम पर फिर से बनाना होगा।

यह गतिविधि सरफेसव्यू पर हर पल एक नया बिटमैप खींचती है, इससे पहले स्क्रीन को साफ किए बिना। यदि आप इसका परीक्षण करते हैं, तो आप देखेंगे कि बिटमैप हमेशा एक ही बफर को नहीं लिखा जाता है, और स्क्रीन दोनों बफ़र्स के बीच वैकल्पिक होगी।

मैंने इसे अपने फोन (Nexus S, Android 2.3.3), और एमुलेटर (Android 2.2) पर परीक्षण किया।

public class TestCanvas extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new TestView(this));
    }
}

class TestView extends SurfaceView implements SurfaceHolder.Callback {

    private TestThread mThread;
    private int mWidth;
    private int mHeight;
    private Bitmap mBitmap;
    private SurfaceHolder mSurfaceHolder;

    public TestView(Context context) {
        super(context);
        mThread = new TestThread();
        mBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.icon);
        mSurfaceHolder = getHolder();
        mSurfaceHolder.addCallback(this);
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {
        mWidth = width;
        mHeight = height;
        mThread.start();
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {/* Do nothing */}

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        if (mThread != null && mThread.isAlive())
            mThread.interrupt();
    }

    class TestThread extends Thread {
        @Override
        public void run() {
            while (!isInterrupted()) {
                Canvas c = null;
                try {
                    c = mSurfaceHolder.lockCanvas(null);
                    synchronized (mSurfaceHolder) {
                        c.drawBitmap(mBitmap, (int) (Math.random() * mWidth), (int) (Math.random() * mHeight), null);
                    }
                } finally {
                    if (c != null)
                        mSurfaceHolder.unlockCanvasAndPost(c);
                }

                try {
                    sleep(1000);
                } catch (InterruptedException e) {
                    interrupt();
                }
            }
        }   
    }
}

ठीक है, ऐसा लगता है कि आप गलत हैं, मेरी स्क्रीन कैप्चर को यहां देखें: img12.imageshack.us/i/devicey.png/# जब आपने एक विलंब जोड़ा है जैसे कि एक दूसरा डबल बफरिंग अधिक देखा जाता है, लेकिन (!) स्क्रीन पर अभी भी पिछले चित्र हैं। इसके अलावा, आपका कोड गलत है: यह होना चाहिए SurfaceHolder.Callback, न कि सिर्फ Callback
Wroclai

1
मुझे लगता है कि आपको समझ नहीं आ रहा है कि मेरा क्या मतलब है। कोई क्या उम्मीद कर सकता है कि फ्रेम एन और फ्रेम एन + 1 के बीच अंतर यह है कि एक और बिटमैप है। लेकिन यह पूरी तरह से गलत है, फ्रेम एन और फ्रेम एन + 2 के बीच एक और बिटमैप है , लेकिन फ्रेम एन और फ्रेम एन + 1 पूरी तरह से असंबंधित हैं, भले ही मैंने सिर्फ एक बिटमैप जोड़ा हो।
गुइलुम ब्रूनरी

नहीं, मैं आपको पूरी तरह से समझता हूं। लेकिन, जैसा कि आप देखते हैं, आपका कोड काम नहीं करता है। थोड़ी देर के बाद, स्क्रीन आइकन से भरा होता है। इसलिए, Canvasयदि हमें पूरी स्क्रीन को पूरी तरह से रीडायरेक्ट करना है , तो हमें इसे साफ़ करना होगा। यह "पिछले चित्र" के बारे में मेरा कथन सच बनाता है। Canvasपिछले चित्र रहता है।
व्रोकलाई

4
यदि आप चाहें तो हाँ, Canvasपिछले चित्र रखता है। लेकिन यह पूरी तरह से बेकार है, समस्या यह है कि जब आप उपयोग करते lockCanvas()हैं तो आपको नहीं पता कि वे "पिछले ड्राइंग" क्या हैं, और उनके बारे में कुछ भी नहीं मान सकते हैं। शायद इसलिए कि अगर एक ही आकार के सरफेस व्यू के साथ दो गतिविधियाँ होती हैं, तो वे एक ही कैनवस को साझा करेंगे। शायद कि आपको इसमें यादृच्छिक बाइट्स के साथ असंबद्ध रैम का एक हिस्सा मिलता है। शायद इसलिए हमेशा कैनवास में गूगल लोगो लिखा रहता है। आप नहीं जान सकते। कोई भी एप्लिकेशन जो lockCanvas(null)टूट जाने के बाद हर पिक्सेल को नहीं खींच रहा है।
गिलौम ब्रूनरी

1
@GuillaumeBrunerie 2.5 वर्ष के बाद मैं आपके पोस्ट पर आया हूं। आधिकारिक एंड्रॉइड डॉक्यूमेंटेशन "हर पिक्सेल को ड्रॉ करने" से संबंधित आपकी सलाह का समर्थन करता है। केवल एक ही मामला है जहां कैनवास के एक हिस्से की गारंटी दी जाती है, फिर भी लॉककैनवास () के लिए कॉल के साथ होना चाहिए। सर्फेसहॉल्डर और इसके दो लॉककैनवास () विधियों के लिए Android प्रलेखन का संदर्भ लें। developer.android.com/reference/android/view/... और developer.android.com/reference/android/view/...
UpLate

3

मेरे लिए कॉलिंग Canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR)या ऐसा ही कुछ काम होगा जब मैं स्क्रीन को टच करूंगा। इसलिए मैं उपरोक्त लाइन ऑफ कोड को कॉल करूंगा लेकिन स्क्रीन तभी साफ होगी जब मैं स्क्रीन को टच करूंगा। तो क्या मेरे लिए काम किया कहते थे invalidate(), जिसके बाद init()जो निर्माण के समय कहा जाता है दृश्य प्रारंभ करने में।

private void init() {
    setFocusable(true);
    setFocusableInTouchMode(true);
    setOnTouchListener(this);

    mPaint = new Paint();
    mPaint.setAntiAlias(true);
    mPaint.setDither(true);
    mPaint.setColor(Color.BLACK);
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setStrokeJoin(Paint.Join.ROUND);
    mPaint.setStrokeCap(Paint.Cap.ROUND);
    mPaint.setStrokeWidth(6);

    mCanvas = new Canvas();
    mPaths = new LinkedList<>();

    addNewPath();
}

3
canvas.drawColor(Color.TRANSPARENT, Mode.MULTIPLY);

2
कृपया इस बात की व्याख्या जोड़ें कि आपका कोड समस्या को कैसे हल करता है। इसे निम्न गुणवत्ता वाले पोस्ट के रूप में चिह्नित किया गया है - समीक्षा से
सूरज राव

1

जावा एंड्रॉइड में कैनवस पर इरेज़िंग करना एचटीएमएल कैनवस को जावास्क्रिप्ट के माध्यम से वैश्वीकरण के साथ मिटा रहा है। तर्क भी ऐसा ही था।

U, DST_OUT (गंतव्य आउट) तर्क का चयन करेगा।

paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));

नोट: DST_OUT अधिक उपयोगी है क्योंकि यह 50% मिटा सकता है यदि पेंट का रंग 50% अल्फा है। तो, पूरी तरह से पारदर्शी होने के लिए, रंग का अल्फा 100% होना चाहिए। पेंट लागू करें। रंगरूट (Color.WHITE) की सिफारिश की जाती है। और सुनिश्चित करें कि कैनवास छवि प्रारूप RGBA_8888 था।

मिटने के बाद, SRC_OVER (सोर्स ओवर) के साथ सामान्य ड्राइंग पर वापस जाएं।

paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER));

अद्यतन छोटे क्षेत्र प्रदर्शन शाब्दिक ग्राफिक हार्डवेयर का उपयोग करने की आवश्यकता होगी, और यह शायद समर्थित नहीं है।

उच्चतम प्रदर्शन के लिए सबसे करीब बहु छवि परत का उपयोग किया जाता है।


क्या आप यहाँ मेरी मदद कर सकते हैं? तुम्हारा एकमात्र समाधान है जिसने मेरे मामले के लिए काम किया है इसलिए मैंने मतदान किया है, बस थोड़ी समस्या है जिसे हल करने की आवश्यकता है
हमजा खान

मैं सतह धारक के साथ कैनवास का उपयोग कर रहा हूं, इसलिए मैं कैनवस (सतह धारक से लिया गया कैनवास) को साफ करने के लिए ऐसा करता हूं: पेंट !!। setXfermode (PorterDuffXfermode (PorterDuff.Mode.DST_OUT)) कैनवास)। DrawPaint (पेंट)! .unlockCanvasAndPost (कैनवस) तब इसे फिर से सक्रिय करने में सक्षम होने के लिए: पेंट !! कैनवास को इस तरह साफ़ करने के बाद, जब मैं कैनवास पर एक बिटमैप खींचता हूँ, तो उसे ब्लिंक के बाद खींचा जाता है, जो कि कष्टप्रद है, क्या आप मुझे यहाँ रास्ता दिखा सकते हैं? @phnghue
खान

@hamza khan क्या आपने SRC_OVER के साथ प्रयास किया है? क्योंकि SRC_OVER डिफ़ॉल्ट सामान्य है। SRC तर्क पुराने पिक्सेल डेटा को अधिलेखित कर देता है, यह अल्फा को बदल देता है!
फेनघे


0

किसी गतिविधि के onPause () पर दृश्य को निकालने का प्रयास करें और onRestart () जोड़ें

LayoutYouAddedYourView.addView (YourCustomView); LayoutYouAddedYourView.removeView (YourCustomView);

जिस क्षण आप अपना दृष्टिकोण जोड़ते हैं, onDraw () विधि कहलाती है।

YourCustomView, एक वर्ग है जो दृश्य वर्ग का विस्तार करता है।


0

मेरे मामले में, मैं अपने कैनवस को रेखाचित्र में शामिल करता हूं। फिर से साफ और लाल करने के लिए:

    LinearLayout linearLayout = findViewById(R.id.myCanvas);
    linearLayout.removeAllViews();

और फिर, मैं कक्षा को नए मूल्यों के साथ कहता हूं:

    Lienzo fondo = new Lienzo(this,items);
    linearLayout.addView(fondo);

यह वर्ग Lienzo है:

class Lienzo extends View {
    Paint paint;
    RectF contenedor;
    Path path;
    ArrayList<Items>elementos;

    public Lienzo(Context context,ArrayList<Items> elementos) {
        super(context);
        this.elementos=elementos;
        init();
    }

    private void init() {
        path=new Path();
        paint = new Paint();
        contenedor = new RectF();
        paint.setStyle(Paint.Style.FILL);
    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        contenedor.left = oneValue;
        contenedor.top = anotherValue;
        contenedor.right = anotherValue;
        contenedor.bottom = anotherValue;

        float angulo = -90; //starts drawing at 12 o'clock
        //total= sum of all element values
        for (int i=0;i<elementos.size();i++){
            if (elementos.get(i).angulo!=0 && elementos.get(i).visible){
                paint.setColor(elementos.get(i).backColor);
                canvas.drawArc(contenedor,angulo,(float)(elementos.get(i).value*360)/total,true,paint);

                angulo+=(float)(elementos.get(i).value*360)/total;
            }
        } //for example
    }
}

0

निम्नलिखित दृष्टिकोण के साथ, आप पूरे कैनवास या इसके एक हिस्से को साफ कर सकते हैं।
कृपया PorterDuff.Mode.ode के बाद से हार्डवेयर त्वरण को अक्षम करने के लिए मत भूलना। हार्डवेयर त्वरण के साथ काम नहीं करता है और अंत में कॉल करता है setWillNotDraw(false)क्योंकि हम onDrawविधि को ओवरराइड करते हैं ।

//view's constructor
setWillNotDraw(false);
setLayerType(LAYER_TYPE_SOFTWARE, null);

//view's onDraw
Paint TransparentPaint = new Paint();
TransparentPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
canvas.drawRect(0, 0, width, height, TransparentPaint); 

यह काम कर रहा है, लेकिन इसके बाद मेरा ड्रॉ अधिक दिखाई नहीं दिया
डायनो क्राइस

1
@DynoCris शायद आप एक ही पेंट ऑब्जेक्ट का उपयोग कर रहे हैं !? एक नए के साथ प्रयास करें, और कृपया मत भूलना।
ucMedia

यह मेरा कोड pastebin.com/GWBdtUP5 है जब मैं फिर से ड्रॉ करने की कोशिश करता हूं तो मुझे अधिक अनफ़ॉरटनल लाइन दिखाई नहीं देती है। लेकिन कैनवस स्पष्ट है।
डायनो क्राइस

1
कृपया परिवर्तन @DynoCris LAYER_TYPE_HARDWAREलिएLAYER_TYPE_SOFTWARE
ucMedia

1
ओह, वास्तव में, यह मेरी गलती है। लेकिन इसने मुझे वैसे भी मदद नहीं की।
डायनो क्राइस

-1

आपकी पहली आवश्यकता, पूरे कैनवास को कैसे साफ़ या फिर से परिभाषित करें - उत्तर - स्क्रीन को काले या जो कुछ भी आप निर्दिष्ट करते हैं, स्क्रीन को साफ़ करने के लिए कैनवास का उपयोग करें। color (कलर। बैक)।

आपकी दूसरी आवश्यकता, स्क्रीन के भाग को कैसे अपडेट किया जाए - उत्तर - उदाहरण के लिए यदि आप स्क्रीन पर अन्य सभी चीजों को अपरिवर्तित रखना चाहते हैं, लेकिन पूर्णांक दिखाने के लिए स्क्रीन के एक छोटे से क्षेत्र में (कहते हैं काउंटर) जो हर पांच सेकंड के बाद बढ़ता है। फिर कैनवास का उपयोग करें। उस छोटे से क्षेत्र को बाईं ओर दाईं ओर नीचे और पेंट करके निर्दिष्ट करने के लिए सही विधि का उपयोग करें। फिर अपने काउंटर मान की गणना करें (5 सेकंड के लिए पोस्टडालयड का उपयोग करते हुए, हैंडलर .postDelayed (Runnable_Object, 5000);) को लाइक करें, इसे टेक्स्ट स्ट्रिंग में कनवर्ट करें, इस छोटे आयत में x और y समन्वय करें और बदलते हुए डिस्प्ले को देखने के लिए टेक्स्ट व्यू का उपयोग करें। विपरीत - मूल्य।


-1

मुझे कैनवास को साफ़ करने के लिए एक अलग ड्राइंग पास का उपयोग करना पड़ा (लॉक, ड्रॉ और अनलॉक):

Canvas canvas = null;
try {
    canvas = holder.lockCanvas();
    if (canvas == null) {
        // exit drawing thread
        break;
    }
    canvas.drawColor(colorToClearFromCanvas, PorterDuff.Mode.CLEAR);
} finally {
    if (canvas != null) {
        holder.unlockCanvasAndPost(canvas);
    }
}

-3

बस कॉल करना

canvas.drawColor (Color.TRANSPARENT)


16
यह काम नहीं करता है क्योंकि यह सिर्फ वर्तमान क्लिप के शीर्ष पर पारदर्शिता आकर्षित करेगा ... प्रभावी रूप से कुछ भी नहीं कर रहा है। हालाँकि, आप इच्छित प्रभाव को प्राप्त करने के लिए पोर्टर-डफ ट्रांसफर मोड को बदल सकते हैं Canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR):। अगर मुझसे गलती नहीं हुई है, तो रंग वास्तव में कुछ भी हो सकता है (ट्रांसपेरेंट होना जरूरी नहीं है) क्योंकि PorterDuff.Mode.CLEARवर्तमान क्लिप (कैनवास में एक छेद को छिद्रित करने की तरह ) केवल स्पष्ट होगा।
ashughes
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.