Intereting Posts
Как сделать GridView растяжимым в Android, чтобы расширить ширину столбца до любой степени? Добавить прослушиватель для включения в панель действий Каков список всех триггеров Android Init Language? Как добавить символ новой строки в строку по конкретным индексам? Есть ли рекомендуемая стратегия для выпуска бета-версии приложения для ограниченного числа пользователей через Android Market? Отправлять данные через Wi-Fi (без Интернета), когда мобильные данные по Является ли Fragment.setUserVisibleHint (), вызванным системой Android? Резервное копирование / восстановление общих настроек android Android Lint: как подавить все предупреждения, связанные с библиотекой поддержки? Есть ли способ отличить Android Activity onResume от главного экрана? Предложение SearchView – Ширина макета: match_parent Как поход (версия – 4.6.0.86) показывает кнопку плавающего действия в приложении whatsapp QSettings не работает на Qt под Android Не удалось создать Gradle, если поддержка импорта – v4-22.0.0 Android: Как использовать clipRect в API15

Как установить комбинированный цвет для перекрываемой области двух разных цветовых объектов?

Я создаю различные пользовательские представления с двумя разными цветами. Согласно моим функциям приложения пользователь будет перетаскивать эти объекты на экране, когда перетаскивание объектов будет перекрывать друг друга. Я хочу дифференцировать перекрываемую область, как установить комбинированный цвет для перекрываемой области. Посмотрите на изображение ниже. Здесь я использую холст для создания этих пользовательских представлений. Два круга – это два разных вида.

Введите описание изображения здесь

EDIT: Если я использую opacity 128, я могу видеть цвет фона, но мне нужен цвет комбинации совпадающих объектов.

Смешивание цветов, которое вы ищете, иногда называют интуитивно понятным смешиванием цветов или цветовой системой RYB :

RYB :

Введите описание изображения здесь Лицензия CC

В цитате из этой статьи Натана Госсетта и Баокуана Чена по алгоритмам интуитивного смешения цветов обобщается, как работает интуитивно понятная система окраски:

«В этой модели красные, желтые и синие используются в качестве чистых основных цветов. Красное и желтое смешивание для формирования оранжевого, желтого и синего смесей с образованием зеленого, синего и красного смешивания для формирования фиолетового […]. Цвета, которые нетренированный зритель ожидал бы получить с помощью детской краски […]. Кроме того, многие люди не думают о Белом как о смеси всех цветов, а вместо этого о том, как отсутствие цвета (пустой холст). Предположение заключалось бы в том, что смешивание многих цветов вместе приведет к мутному темно-коричневому цвету ».

RYB не реализован в режимах смешивания Android и не может быть имитирован путем смешивания альфа / разных режимов смешивания.

Большинство приложений компьютерной графики используют цветовые пространства RGB или CMYK :

CMYK :

Введите описание изображения здесь Лицензия CC

CMY основан на субтрактивном цвете. Субтрактивное смешивание цветов означает, что, начиная с белого цвета, при добавлении цвета результат становится темнее. CMYK используется для смешивания цветов в изображениях, предназначенных для печати, например, Photoshop и Illustrator.

RGB :

Введите описание изображения здесь Лицензия CC

RGB основан на добавочном цвете. Цвета на экране компьютера создаются с помощью света с использованием метода добавочного цвета. Смешивание добавочного цвета начинается с черного цвета и при добавлении большего количества цвета результат становится светлее и заканчивается белым.

На этом сайте более подробно рассматриваются CMYK и RGB.

Ни RGB, ни CMYK не смешивают синие и желтые зеленые или, вообще говоря, интуитивные цветовые смеси. Для внедрения цветовой системы RYB на Android было бы очень сложно. В статье Натана Госсетта и Баокуана Чена, приведенных выше, предлагается решение с алгоритмом, реализованным на C в самом конце статьи. Этот алгоритм может быть реализован в пользовательской смеси на Android. Drawable.setColorFilter() использует PorterDuffColorfilter который расширяет ColorFilter . Подклассификация ColorFilter как обсуждалось в этом вопросе SO, должна быть выполнена в собственном коде с использованием NDK.

Смешивание CMYK

Если вы заинтересованы в использовании смешивания цветов CMYK в качестве обходного пути, я включил базовый пример того, как это можно сделать ниже. В этом примере круг с циановым цветом и круг желтого цвета будут смешаны для получения зеленого пересечения.

Начиная с этих .png файлов изображений, созданных в Adobe Illustrator:

Введите описание изображения здесь

Введите описание изображения здесь

С шестнадцатеричным значением цвета 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% («88» в «0x88ffff00»). Для желтого это работает разумно, но для других цветов альфа-эффект может быть неприемлем (цвет может выглядеть другим цветом, например, красный становится розовым с низкими значениями альфа на белом фоне). Какой режим смешивания в конечном счете приемлем для вас, зависит от набора цветов, которые вы собираетесь использовать, и предпримет некоторые эксперименты. Также обратите внимание, что цвет фона может влиять на цвета кругов в режиме наложения. В этом примере фон установлен на белый.

Я сделал еще один пример для 6 объектов.

Введите описание изображения здесь

Ключевые моменты:

  1. Метод onDraw не будет переопределяться для представлений объектов, а фон также будет установлен на прозрачность

    setBackgroundColor (Color.TRANSPARENT);

  2. Но метод onDraw будет переименован в onDrawEx, который вызывается из Overlay View.

    Public void onDrawEx (холст холста) {

  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 (новый 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)); 

Я использовал параметр макета для перевода.

Самое простое решение, о котором я могу думать, это просто использовать альфа-канал, установив каждый на 0,5 прозрачности, либо в код, либо в xml. Затем цвета должны исчезать друг в друга, когда они перекрываются. Это означает, что цвета в неперекрывающихся разделах будут немного поблекшими, и в зависимости от того, какой фон у вас за фигурами, может показаться не очень хорошим, чтобы они были абсолютно прозрачными.

Я создал образец Activity с двумя представлениями 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); Чтобы получить необходимый цвет в соответствии с вашей логикой.

Я использую setTranslationX setTranslationY для перемещения представлений.

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

Я думаю, вы можете смотреть в режиме наложения. Android позволит вам сделать это, просто взгляните на эту первую ссылку. Композитные операции в Android Canvas

Вот все варианты компоновки http://developer.android.com/reference/android/graphics/PorterDuffXfermode.html

И их объяснения из Mozilla https://developer.mozilla.org/en/Canvas_tutorial/Compositing