Android Canvas меняет цвет пересечения фигур и текстов
и:
"Если круг и прямоугольник одновременно белые, а фон черный. КогдаЯ изменяю цвет фона на любой другой цвет , текст не виден, фигуры черные. "
PorterDuff
(1)Да, мы можем с PorterDuff.Mode
(Mode.ADD
):
PorterDuff.Mode mode = Mode.ADD;
(2)Canvas
фон должен быть transparent
, чтобы compositing
работал.Если вам нужен любой другой цвет фона , тогда нам нужно сделать наложение на отдельно Canvas
.Затем мы копируем чертеж в оригинал Canvas
.
«Мне также интересно, как я могу получить аналогичные результаты, как в этом изображении»
Вот вывод кода (PorterDuff
определяет цвет смешивания; O ():
(Q1 :) «Можно ли установить перекрывающиеся участки для круга, прямоугольника и текста на определенный цвет?»
- (A1 :) Да, это может бытьсделано (с большими усилиями). Почти закончено, но уверено, что может. Вот почти готовые изображения (в этом ответе мне пришлось использовать почти все вещи, должен быть более простым способом ...):
Код
@Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
Paint paint = new Paint();
Paint paintClear = new Paint();
TextPaint textPaint = new TextPaint();
int width = getWidth();
int height = getHeight();
int x = 100;
int y = 100;
int radius = 100;
PorterDuff.Mode mode = Mode.ADD; // mode Mode.ADD
paintClear.setStyle(Style.FILL);
paint.setStyle(Style.FILL);
textPaint.setAntiAlias(true);
textPaint.setTextSize(100 * getResources().getDisplayMetrics().density);
textPaint.setColor(Color.GREEN);
textPaint.setStrokeWidth(3);
// ** clear canvas backgound to white**
paintClear.setColor(Color.WHITE);
canvas.drawPaint(paintClear);
//canvas.save();
Bitmap compositeBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
Canvas compositeCanvas = new Canvas(compositeBitmap);
paintClear.setColor(Color.TRANSPARENT);
compositeCanvas.drawPaint(paintClear);
// ** draw destination circle in red **
paint.setColor(Color.RED);
compositeCanvas.drawCircle(x+100, y+100, radius, paint);
// ** set Xfermode **
paint.setXfermode(new PorterDuffXfermode(mode));
textPaint.setXfermode(new PorterDuffXfermode(mode));
// ** draw source circle in blue **
paint.setColor(Color.BLUE);
compositeCanvas.drawCircle(x-0, y-0, radius, paint);
// ** draw text in Green **
compositeCanvas.save();
compositeCanvas.rotate(-45, x, y+150);
compositeCanvas.drawText("- 65,6", x, y+150, textPaint);
compositeCanvas.restore();
//copy compositeCanvas to canvas
canvas.drawBitmap(compositeBitmap, 0, 0, null);
//canvas.restore();
}//onDraw
Проверка пересечения
Использование RectF содержит и пересекается:
public Rect mBound = new Rect(0 , 0 , 10 , 10);
public RectF a1 = new Rect(0f , 0f , 10f, 10f);
public RectF b1 = new Rect(5f , 5f , 20f, 20f);
public RectF c1 = new Rect(30f, 30f, 40f, 40f);
int boolean hit = false;
int boolean intersect = false;
hit = hitTest(20,15); // returns false
hit = hitTest(5,5); // returns true
intersect = intersectsTest(a1,b1);// returns true
intersect = intersectsTest(a1,c1);// returns false
public boolean hitTest(int x, int y)
{
return mBound.contains(x, y);
}//
// Returns true if the two specified rectangles intersect
public boolean intersectsTest(RectF a, RectF b)
{
return intersects ( a, b);
}//
Заметки
Вы указали, что хотите узнать больше о цветном рисовании, вот некоторые вещи, с которыми я играл.
Эксперименты с setColorFilter
и ColorMatrixColorFilter
:
textPaint.setColorFilter(new ColorMatrixColorFilter(getColorMatrix5()));//custom 5
//custom 5
private ColorMatrix getColorMatrix5()
{
ColorMatrix colorMatrix = new ColorMatrix();
colorMatrix.setSaturation(0);//make it greyscale
ColorMatrix blueMatrix = new ColorMatrix(new float[] {
0, 0, 0, 0, 0, // red
0, 0, 0, 0, 0, // green
1, 1, 1, 1, 1, // blue
1, 1, 1, 1, 1 // alpha
});
// Convert, then scale and clamp
colorMatrix.postConcat(blueMatrix);
return colorMatrix;
}//getColorMatrix1
Настройка PorterDuff
Звучит так, будто вам нужно Custom PorterDuff
.Вот некоторый код, чтобы дать вам представление о том, как его написать (Android
использует библиотеку, написанную на C++
).
public class MyPorterDuffMode
{
public Bitmap applyOverlayMode(Bitmap srcBmp, Bitmap destBmp)
{
int width = srcBmp.getWidth();
int height = srcBmp.getHeight();
int srcPixels[] = new int[width * height];
int destPixels[] = new int[width * height];
int resultPixels[] = new int[width * height];
int aS = 0, rS = 0, gS = 0, bS = 0;
int rgbS = 0;
int aD = 0, rD = 0, gD = 0, bD = 0;
int rgbD = 0;
try
{
srcBmp.getPixels(srcPixels, 0, width, 0, 0, width, height);
destBmp.getPixels(destPixels, 0, width, 0, 0, width, height);
srcBmp.recycle();
destBmp.recycle();
}
catch(IllegalArgumentException e)
{
}
catch(ArrayIndexOutOfBoundsException e)
{
}
for(int y = 0; y < height; y++)
{
for(int x = 0; x < width; x++)
{
rgbS = srcPixels[y*width + x];
aS = (rgbS >> 24) & 0xff;
rS = (rgbS >> 16) & 0xff;
gS = (rgbS >> 8) & 0xff;
bS = (rgbS ) & 0xff;
rgbD = destPixels[y*width + x];
aD = ((rgbD >> 24) & 0xff);
rD = (rgbD >> 16) & 0xff;
gD = (rgbD >> 8) & 0xff;
bD = (rgbD ) & 0xff;
//overlay-mode
rS = overlay_byte(rD, rS, aS, aD);
gS = overlay_byte(gD, gS, aS, aD);
bS = overlay_byte(bD, bS, aS, aD);
aS = aS + aD - Math.round((aS * aD)/255f);
resultPixels[y*width + x] = ((int)aS << 24) | ((int)rS << 16) | ((int)gS << 8) | (int)bS;
}
}
return Bitmap.createBitmap(resultPixels, width, height, srcBmp.getConfig());
}
// kOverlay_Mode
int overlay_byte(int sc, int dc, int sa, int da)
{
int tmp = sc * (255 - da) + dc * (255 - sa);
int rc;
if (2 * dc <= da)
{
rc = 2 * sc * dc;
}
else
{
rc = sa * da - 2 * (da - dc) * (sa - sc);
}
return clamp_div255round(rc + tmp);
}
int clamp_div255round(int prod)
{
if (prod <= 0)
{
return 0;
}
else if (prod >= 255*255)
{
return 255;
}
else
{
return Math.round((float)prod/255);
}
}
}//class MyPorterDuffMode
Ссылка на код
См. PorterDuff , PorterDuff.Mode
, PorterDuffXfermode
, ColorFilter
, ColorMatrix , ColorMatrixColorFilter , PorterDuffColorFilter , Canvas
, Color
.