2012-08-07 22 views
15

Renkler bir katkı maddesi olacak şekilde bir Tuval üzerine grafik boyamak istiyorum.
Proper additive colorsAlfa ile nasıl boya yapılır?

Ama bunun yerine, bu alın: Örneğin, ben bu üretmek isteyen alfa hem nasıl etkileşimde
My results

Not yarısı beyaz, yarısı siyah arka plan kasıtlı olduğunu, sadece görmek için arka planlar. Bu çalışmayı arka plana sahip olmaktan mutluluk duyacağım. İşte benim kodudur:

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)); 
    } 
} 

biri bana Android grafikleri katkı renkleriyle resim nasıl anlamanıza yardımcı misiniz?

cevap

26

Doğru yoldasınız. Kodunuzdaki 3 büyük sorunlar vardır: Hepsini görsel oluşturma için mod iso renk filtresi

  • Kullanım sıcaklığı bit eşlem havalesine ayarlamanız gerekir

    • Alfa Aradığınız sonuçları almak için 0xFF olmalıdır

    İşte xfer modunu kullanarak sahip olduğum şey. Yaptığım şey - her şeyi geçici bir bitmap haline getirip tüm bitmap'i ana tuvale aktarıyor. Sen sor

    xfer mode rules

    neden geçici bitmap gerekiyor? İyi soru! Her şeyi bir ana tuval üzerine çiziyorsanız, renkleriniz ana tuval arkaplan rengi ile harmanlanacak, böylece tüm renkler berbat olacaktır. Saydam geçici bitmap, renklerinizi UI'nin diğer parçalarından uzak tutmanıza yardımcı olur. onDraw()'da hiçbir şey tahsis etmediğinizden emin olun - bu şekilde çok yakında belleği dolduracaksınız. Ayrıca, geçici bitmap'inizi geri dönüştürdüğünüzden emin olun. Artık ihtiyacın olduğunda.

    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

    Çok teşekkürler, Pavel; ve çok hızlı! –

    +3

    BTW, SDK sürüm 8 ile uyumlu PorterDuff.Mode.ADD için bir alternatif biliyor musunuz? Dokümantasyon, ADD'nin 8 sürümünde eklendiğini ama yalan olduğunu söylüyor. Gerçekten, 11 sürümünde tanıtıldı ve widget'ımı yüklemesine izin verilmemesi gereken bazı eski cihazlarda çöküyordu. –

    +1

    Bu harika!Bu tekniği birbiriyle çakışan bitmap'lere uygulayabilir misiniz? –

    2

    Tekrar teşekkürler Pavel. Bu benim kendi başıma tanımlamam çok zor olurdu. Ayrıntıları daha iyi incelemek için kendi sorumu yanıtlıyorum, ama ben sizinkileri en iyi cevap olarak kabul ettim.

    Ekran dışı bir Bitmap (ve Canvas) oluşturup yönetmemeyi tercih etmekteyim. Bu yüzden, bu işi yapmak için siyah veya beyaz bir arka planın iyi olacağını söylemiştim.

    Bir şey görmeden önce performansla asla ilgilenmiyorum ama bu noktadan sonra dikkatinizi paylaşıyorum. Bunu düzeltmek ve bu üyeleri kaldırmak için sürümünüzü düzenlemek aşağıdaki uygulamayı verir.

    Bu sağlam mıdır? Biriyle birleştirilebileceğinden şüphelendiğim iki Canvas.drawColor() çağrısına dikkat edin.

    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

    bu çözüm de doğrudur. Ayrı bitmap kullanmamı önerdim çünkü genellikle yalnızca istediğiniz renkleri karıştırmak ve UI'nin geri kalanıyla karışıklık yaratmak istemiyorsunuz. Kodunuza yapılan tek bir açıklama, 'canvas.drawColor (Color.BLACK);' tuval.drawColor (Color.TRANSPARENT, Mode.CLEAR); Yani teoride –

    +0

    @Melinda Green'i düşürdüğüm her düğmede tuvalin boya rengini nasıl değiştirebilirim? Böylece farklı bir arka plan renkleri verebilir. – Erum

    +0

    @Erum Hannan Düğmenin onClick yönteminde bir renk depola ve ayarla Bu withDraw içinde onunla canvas.drawColor ile arka plan olarak renk. –

    İlgili konular