Intereting Posts
Как проверить, подписана ли APK или «отладить сборку»? Android: как создать 3 вертикальные точки? Грейд-зависимость, основанная на обоих типах сборки и вкусе Android Studio: новый созданный каталог не отображается в папках Android Google Admob: ресурсы сервисов Google Play не найдены Арабский номер в арабском тексте на Android Подходящее устройство Android для инженерного проекта Как сохранить изображения с камеры в Android в определенную папку? Как показать тост в AsyncTask в android Сделать SurfaceView прозрачным без setZOrderOnTop (true) Android: создание родительского макета и расширение его, чтобы поддерживать одинаковый внешний вид во всех действиях приложения Как просматривать / отлаживать нестандартные заголовки запросов, отправляемых браузером моего телефона? Проект Android Studio Gradle «Невозможно запустить процесс / инициализацию виртуальной машины» Отсутствует Xamarin sider.dll Сохранение пользовательского интерфейса при изменении ориентации – onSaveInstanceState не работает, как ожидалось, если сохранить фрагмент

Стереть части растровых изображений с помощью режима PorterDuff

Я пытаюсь стереть части растрового изображения в приложении для Android, используя Porter-Duff Xfermodes.

У меня есть зеленый фон, который накладывается синим растровым изображением. Когда я прикасаюсь к экрану, должно быть создано «отверстие» в наложенном растровом изображении, что делает зеленый фон видимым. Вместо отверстия мой текущий код создает черную точку.

Ниже мой код. Любые идеи, что я здесь делаю неправильно?

/** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); setContentView(new DrawView(this)); } public class DrawView extends View implements OnTouchListener { private int x = 0; private int y = 0; Bitmap bitmap; Canvas bitmapCanvas; private final Paint paint = new Paint(); private final Paint eraserPaint = new Paint(); public DrawView(Context context) { super(context); setFocusable(true); setFocusableInTouchMode(true); this.setOnTouchListener(this); // Set background this.setBackgroundColor(Color.GREEN); // Set bitmap bitmap = Bitmap.createBitmap(320, 480, Bitmap.Config.RGB_565); bitmapCanvas = new Canvas(); bitmapCanvas.setBitmap(bitmap); bitmapCanvas.drawColor(Color.BLUE); // Set eraser paint properties eraserPaint.setAlpha(0); eraserPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN)); eraserPaint.setAntiAlias(true); } @Override public void onDraw(Canvas canvas) { bitmapCanvas.drawColor(Color.BLUE); bitmapCanvas.drawCircle(x, y, 10, eraserPaint); canvas.drawBitmap(bitmap, 0, 0, paint); } public boolean onTouch(View view, MotionEvent event) { x = (int) event.getX(); y = (int) event.getY(); invalidate(); return true; } } 

Solutions Collecting From Web of "Стереть части растровых изображений с помощью режима PorterDuff"

Во-первых, я не уверен, что настройка альфа-0 на ваш объект рисования красок – хорошая идея. Это может сделать все это неэффективным.

Кроме того, вы всегда должны использовать Bitmap.Config.ARGB_8888, если вы имеете дело с альфа.

Если у вас возникнут проблемы с материалом PorterDuff, я бы предложил упростить ваш подход, чтобы ТОЛЬКО делать это (временно). Это поможет вам сузить часть, которая не работает. Прокомментируйте все, что касается касания и просмотра обновлений.

Затем вы можете указать, какая часть чертежа работает неправильно. Настройте свой конструктор следующим образом:

 DrawView() { /* Create the background green bitmap */ ... /* Create foreground transparent bitmap */ ... /* Draw a blue circle on the foreground bitmap */ ... /* Apply the foreground to the background bitmap using a PorterDuff method */ ... } onDraw() { /* Simply draw the background bitmap */ ... } 

Если вы это настроите, вы должны быть в состоянии сказать, как ваш метод PD влияет на зеленый растровый рисунок, и соответствующим образом изменить ситуацию.

Вот рабочий код … может помочь кому-то

 public class ImageDemo extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new Panel(this)); } class Panel extends View { private Bitmap mBitmap; private Canvas mCanvas; private Path mPath; private Paint mPaint; Bitmap bitmap; Canvas pcanvas; int x = 0; int y =0; int r =0; public Panel(Context context) { super(context); Log.v("Panel", ">>>>>>"); setFocusable(true); setBackgroundColor(Color.GREEN); // setting paint mPaint = new Paint(); mPaint.setAlpha(0); mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN)); mPaint.setAntiAlias(true); // getting image from resources Resources r = this.getContext().getResources(); Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.mickey); // converting image bitmap into mutable bitmap bitmap = bm.createBitmap(295, 260, Config.ARGB_8888); pcanvas = new Canvas(); pcanvas.setBitmap(bitmap); // drawXY will result on that Bitmap pcanvas.drawBitmap(bm, 0, 0, null); } @Override protected void onDraw(Canvas canvas) { // draw a circle that is erasing bitmap pcanvas.drawCircle(x, y, r, mPaint); canvas.drawBitmap(bitmap, 0, 0,null); super.onDraw(canvas); } @Override public boolean onTouchEvent(MotionEvent event) { // set parameter to draw circle on touch event x = (int) event.getX(); y = (int) event.getY(); r =20; // At last invalidate canvas invalidate(); return true; } } } 

Вот еще одно решение для вашего решения … См. Пример Demo

 public class MainActivity extends Activity { Bitmap bp; Canvas bitmapCanvas; DrawView drawImg; LinearLayout ln1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ln1 = (LinearLayout) findViewById(R.id.ln1); drawImg = new DrawView(this); ln1.addView(drawImg); } public class DrawView extends View implements View.OnTouchListener { private int x = 0; private int y = 0; Bitmap bitmap; Path circlePath; Paint circlePaint; private final Paint paint = new Paint(); private final Paint eraserPaint = new Paint(); public DrawView(Context context){ super(context); setFocusable(true); setFocusableInTouchMode(true); this.setOnTouchListener(this); // Set background this.setBackgroundColor(Color.CYAN); bp = BitmapFactory.decodeResource(getResources(), R.drawable.bg); // Set bitmap bitmap = Bitmap.createBitmap(320, 480, Bitmap.Config.ARGB_8888); bitmapCanvas = new Canvas(); bitmapCanvas.setBitmap(bitmap); bitmapCanvas.drawColor(Color.TRANSPARENT); bitmapCanvas.drawBitmap(bp, 0, 0, null); circlePath = new Path(); circlePaint = new Paint(); circlePaint.setAntiAlias(true); circlePaint.setColor(Color.BLUE); circlePaint.setStyle(Paint.Style.STROKE); circlePaint.setStrokeJoin(Paint.Join.MITER); circlePaint.setStrokeWidth(4f); // Set eraser paint properties eraserPaint.setAlpha(0); eraserPaint.setStrokeJoin(Paint.Join.ROUND); eraserPaint.setStrokeCap(Paint.Cap.ROUND); eraserPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); eraserPaint.setAntiAlias(true); } @Override public void onDraw(Canvas canvas) { canvas.drawBitmap(bitmap, 0, 0, paint); bitmapCanvas.drawCircle(x, y, 30, eraserPaint); canvas.drawPath(circlePath, circlePaint); } public boolean onTouch(View view, MotionEvent event) { x = (int) event.getX(); y = (int) event.getY(); bitmapCanvas.drawCircle(x, y, 30, eraserPaint); circlePath.reset(); circlePath.addCircle(x, y, 30, Path.Direction.CW); int ac=event.getAction(); switch(ac){ case MotionEvent.ACTION_UP: Toast.makeText(MainActivity.this, String.valueOf(x), Toast.LENGTH_SHORT).show(); circlePath.reset(); break; } invalidate(); return true; } } } 

прочитайте больше