26

2 つの異なる色で異なるカスタム ビューを作成しています。私のアプリの機能によると、ユーザーはそれらのオブジェクトを画面上でドラッグします。オブジェクトをドラッグすると、オブジェクトが互いに重なります。重なり部分を区別したいので、重なり部分の合成色の設定方法を教えてください。下の画像を見てください。ここでは、これらのカスタム ビューを作成するためにキャンバスを使用しています。2 つの円は 2 つの異なるビューです。

ここに画像の説明を入力

編集: 不透明度128を使用すると、背景色を見ることができますが、重なっているオブジェクトの色の組み合わせの色が必要です。

4

6 に答える 6

20

あなたが探している混色は、直感的な混色、またはRYBカラーシステムと呼ばれることもあります。

RYB

ここに画像の説明を入力してください CCライセンス

直感的な混色のアルゴリズムに関するNathanGossettとBaoquanChenによるこの論文からの引用は、直感的なカラーシステムがどのように機能するかを要約しています。

「このモデルでは、赤、黄、青を純粋な原色として使用しています。赤と黄を混ぜてオレンジを作り、黄と青を混ぜて緑を作り、青と赤を混ぜて紫を作ります[...]。訓練を受けていない視聴者が子供の絵の具を使って得ることを期待する色[...]。さらに、多くの人々は白をすべての色の混合物としてではなく、色の欠如(空白のキャンバス)と考えています。多くの色を混ぜ合わせると、濁った濃い茶色になると想定されます。」

RYBはAndroidのブレンドモードでは実装されておらず、アルファ/異なるブレンドモードを混合して実際にシミュレートすることはできません。

ほとんどのコンピュータグラフィックスアプリケーションは、RGBまたはCMYK色空間を利用します。

CMYK

ここに画像の説明を入力してくださいCCライセンス

CMYは減法混色に基づいています。減法混色とは、白から始めて、色を追加すると、結果が暗くなることを意味します。CMYKは、PhotoshopやIllustratorなどでの印刷を目的とした画像の色を混合するために使用されます。

RGB

ここに画像の説明を入力してください CCライセンス

RGBは加法色に基づいています。コンピュータ画面の色は、加法色法を使用して光で作成されます。加法混色は黒で始まり、色が追加されるにつれて、結果は明るくなり、白で終わります。

このサイトでは、CMYKとRGBについて詳しく説明しています。

RGBでもCMYKでも、青と黄色を混合しても緑、または一般的に言えば直感的なカラーミックスは生成されません。AndroidにRYBカラーシステムを実装するには、かなりの作業が必要になります。上で引用したNathanGossettとBaoquanChenの論文は、論文の最後にCで実装されたアルゴリズムを使用したソリューションを提案しています。このアルゴリズムは、Androidのカスタムブレンドで実装できます。を拡張するをDrawable.setColorFilter()使用します。このSOの質問で説明されているサブクラス化は、NDKを使用してネイティブコードで実行する必要があります。PorterDuffColorfilterColorFilterColorFilter

CMYKカラーミキシングの回避策

回避策としてCMYK混色を使用することに興味がある場合は、その方法の基本的な例を以下に示します。この例では、シアン色の円と黄色の円をブレンドして、緑色の交差点を作成します。

AdobeIllustratorで作成されたこれらの.png画像ファイルから始めます。

ここに画像の説明を入力してください

ここに画像の説明を入力してください

16進カラー値0x00ffff(シアン)および0xffff00(イエロー)。

それらをcyancircle.pngおよびyellowcircle.pngという名前でドローアブルフォルダに追加します。

main.xmlレイアウトを次のように構成します。

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" 
    android:background="#ffffff"
    android:padding="30dp">

<ImageView
    android:id="@+id/bluecircle"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/cyancircle">
</ImageView>

<ImageView
    android:id="@+id/yellowcircle"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/yellowcircle" 
    android:layout_marginTop="30dp">
</ImageView>     
</RelativeLayout>

アクティビティを作成します。

import android.app.Activity;
import android.graphics.PorterDuff;
import android.os.Bundle;
import android.widget.ImageView;

public class PorterDuffTestActivity extends Activity {
/** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        ImageView yellowCircle = (ImageView)findViewById(R.id.yellowcircle);

        yellowCircle.getDrawable().setColorFilter(0x88ffff00, PorterDuff.Mode.MULTIPLY);
    }
}

出力:

ここに画像の説明を入力してください

この方法の制限は、トップシェイプのアルファを50%(「0x88ffff00」の「88」)に設定する必要があることです。黄色の場合、これは適切に機能しますが、他の色の場合、アルファ効果は受け入れられない場合があります(たとえば、白の背景で赤がピンクになり、アルファ値が低くなるなど、色が別の色に見える場合があります)。どのブレンドモードが最終的に受け入れられるかは、使用する色のセットによって異なり、ある程度の実験が必要になります。また、ブレンドモードでは、背景色が円の色に影響を与える可能性があることに注意してください。この例では、背景が白に設定されています。

于 2012-07-06T04:52:58.233 に答える
5

6 つのオブジェクトの別の例を作成しました。

ここに画像の説明を入力

キーポイント:

  1. オブジェクト ビューの onDraw メソッドはオーバーライドされず、背景も透明に設定されます

    setBackgroundColor(Color.TRANSPARENT);

  2. ただし、onDrawEx がオーバーレイ ビューから呼び出されるように、onDraw メソッドの名前が変更されます。

    public void onDrawEx(Canvas canvas) {

  3. オーバーレイ ビューは、描画するカスタム キャンバスを渡します。オブジェクト ビューに渡す前に、必要な変換を行います。

        mOverlayView = new View(this){
        @Override
        protected void onDraw(Canvas canvas) {
            Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Config.ARGB_8888);
            Canvas canvasBitmap = new Canvas(bitmap);
            ViewGroup viewGroup = (ViewGroup)getParent();
            for(int i = 0 ; i < viewGroup.getChildCount()-1;i++){
                ObjectView objectView = (ObjectView) viewGroup.getChildAt(i);
                canvasBitmap.save();
                canvasBitmap.translate(objectView.getTranslationX(), objectView.getTranslationY());
                objectView.onDrawEx(canvasBitmap);
                canvasBitmap.restore();
            }
            canvas.drawBitmap(bitmap, 0, 0, new Paint());
        }
    };
    
  4. mPaint.setXfermode(new PorterDuffXfermode(Mode.ADD)); を使用します。色を追加します。しかし、すべてのオブジェクトは 0xFF000030,0xFF0000C0,0xFF003000,0xFF00C000,0xFF300000,0xC00000 のような色を使用する必要があり、すべての可能なオーバーラップに対してのみ異なる色を得ることができます。これは、オブジェクトの最大数に依存します。

        int k = 0 ;
    for(int i = 0 ; i < 2;i++,k++){
        int color = 0xFF000000|(0x000030<<i*2);
        frameLayout.addView(new ObjectView(this,color,k*50,k*50,k), new FrameLayout.LayoutParams(50, 50));
    }
    for(int i = 0 ; i < 2;i++,k++){
        int color = 0xFF000000|(0x003000<<i*2);
        frameLayout.addView(new ObjectView(this,color,k*50,k*50,k), new FrameLayout.LayoutParams(50, 50));
    }
    for(int i = 0 ; i < 2;i++,k++){
        int color = 0xFF000000|(0x300000<<i*2);
        frameLayout.addView(new ObjectView(this,color,k*50,k*50,k), new FrameLayout.LayoutParams(50, 50));
    }
    

ここでは、バージョン 8 をサポートするように変更しました

使用する

mPaint.setXfermode(new PixelXorXfermode(0x00000000));

為に

mPaint.setXfermode(new PorterDuffXfermode(Mode.ADD));

翻訳にはレイアウトパラメータを使用しました。

于 2012-07-07T09:51:54.560 に答える
3

2つのビューDemoDrawShapeActivityを使用してサンプルアクティビティを作成し ました。view2ではcanvas.clipPathとcanvas.translateを使用します。

これを機能させるには、最小のSDKバージョン4を設定します

ここに画像の説明を入力してください

protected void onDraw(Canvas canvas) {
    Paint paint = new Paint();
    paint.setColor(Color.RED);
    path2.addCircle(getWidth()/2, getHeight()/2, getWidth()/2, Direction.CCW);
    canvas.drawPath(path2, paint);
    canvas.clipPath(path2);
    canvas.save();
    canvas.translate(-getTranslationX()+view1.getTranslationX(), -getTranslationY()+view1.getTranslationY());

    paint.setColor(Color.BLUE|Color.RED);
    canvas.drawPath(path1, paint);
    canvas.restore();

}

paint.setColor(Color.BLUE | Color.RED);を編集できます。あなたの論理に従って必要な色を得るために。

setTranslationXsetTranslationYを使用してビューを移動しています。

        public boolean onTouchEvent(MotionEvent event) {
                switch(event.getActionMasked()){
                case MotionEvent.ACTION_UP:
                    touched[0]=touched[1]=false;
                case MotionEvent.ACTION_DOWN:
                case MotionEvent.ACTION_MOVE:
                    if(touched[1]){
                        view2.setTranslationX(event.getX()-view2.getWidth()/2);
                        view2.setTranslationY(event.getY()-view2.getHeight()/2);
                    }else if(touched[0]){
                        view1.setTranslationX(event.getX()-view1.getWidth()/2);
                        view1.setTranslationY(event.getY()-view1.getHeight()/2);
                        view2.invalidate();
                    }
                }
                return true;
            }
于 2012-07-06T07:31:05.697 に答える
3

私が考えることができる最も簡単な解決策は、コードまたはxmlのいずれかで、それぞれを0.5の不透明度に設定してアルファチャンネルを使用することです。次に、色が重なり合うと、色が互いにフェードインするはずです。ただし、これは、重なり合っていないセクションの色が少し薄くなることを意味し、形状の背後にある背景によっては、それらをまったく透明にするのが見栄えがよくない場合があります.

于 2012-07-03T15:02:54.977 に答える
2

ブレンドモードでの描画を検討していると思います。Android ではこれを行うことができます。この最初のリンクを見てください。 Android Canvas での複合操作

すべての合成オプションは次のとおりです http://developer.android.com/reference/android/graphics/PorterDuffXfermode.html

Mozilla からの説明 https://developer.mozilla.org/en/Canvas_tutorial/Compositing

于 2012-07-05T15:48:11.473 に答える
-1

あなたはこれから助けを得るかもしれません -

http://www.learnopengles.com/android-lesson-five-an-introduction-to-blending/

www.pushing-pixels.org/category/android/page/6

于 2012-07-11T07:47:34.330 に答える