Android: как наложить растровое изображение и нарисовать поверх растрового изображения?

На самом деле у меня есть три вопроса:

  1. Что лучше: нарисовать изображение на растровом изображении или создать растровое изображение в качестве ресурса, а затем нарисовать его поверх растрового изображения? Что лучше по производительности?
  2. Если я хочу нарисовать что-то прозрачное поверх растрового изображения, как мне это сделать?
  3. Если я хочу наложить одно прозрачное растровое изображение поверх другого, как мне это сделать?

Извините за длинный список, но в интересах обучения я хотел бы изучить оба подхода.


person Legend    schedule 08.10.2009    source источник


Ответы (5)


Не могу поверить, что на это еще никто не ответил! Редкое явление на SO!

1

Для меня вопрос не совсем понятен. Но я нанесу удар. Если вы спрашиваете о прямом рисовании на холсте (многоугольники, затенение, текст и т. Д.), А не о загрузке растрового изображения и его копировании на холст, это будет зависеть от сложности вашего рисунка. По мере усложнения чертежа требуемое время ЦП соответственно увеличивается. Однако копирование растрового изображения на холст всегда будет постоянным временем, которое пропорционально размеру растрового изображения.

2

Не зная, что такое «что-то», как я могу показать вам, как это сделать? Вы должны понять # 2 из ответа на # 3.

3

Предположения:

  • bmp1 больше, чем bmp2.
  • Вы хотите, чтобы они оба были наложены в верхнем левом углу.

        private Bitmap overlay(Bitmap bmp1, Bitmap bmp2) {
            Bitmap bmOverlay = Bitmap.createBitmap(bmp1.getWidth(), bmp1.getHeight(), bmp1.getConfig());
            Canvas canvas = new Canvas(bmOverlay);
            canvas.drawBitmap(bmp1, new Matrix(), null);
            canvas.drawBitmap(bmp2, new Matrix(), null);
            return bmOverlay;
        }
    
person Declan Shanaghy    schedule 18.02.2010
comment
@Declan Shanaghy, это работает отлично. вы также можете использовать drawBitmap (Bitmap bitmap, float left, float top, Paint paint) для позиционирования, прочтите документацию здесь - person Saifee; 15.03.2016
comment
У меня есть 900 изображений, которые хотелось бы наложить на него .. Он отлично работает, но почему он очень медленный :( за один раз это действительно занимает много времени - person Ahmad Arslan; 26.06.2016
comment
ДЕВЯТЬСОТ! :) - person Fattie; 07.05.2017
comment
Как начать рисовать с левого нижнего угла? @Declan - person sagar suri; 06.04.2019

Вы можете сделать что-то вроде этого:

public void putOverlay(Bitmap bitmap, Bitmap overlay) {
    Canvas canvas = new Canvas(bitmap);
    Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG);
    canvas.drawBitmap(overlay, 0, 0, paint);
} 

Идея очень проста: связав растровое изображение с холстом, вы можете вызвать любой из методов холста для рисования поверх растрового изображения.

Это будет работать для растровых изображений с прозрачностью. Растровое изображение будет иметь прозрачность, если у него есть альфа-канал. Посмотрите Bitmap.Config. Вероятно, вы захотите использовать ARGB_8888.

Важно: посмотрите это Пример Android для различных способов рисования. Это вам очень поможет.

Что касается производительности (точнее, с точки зрения памяти), то лучше всего использовать растровые изображения, поскольку они просто обертывают собственное растровое изображение. ImageView является подклассом View, а BitmapDrawable содержит внутри Bitmap, но также содержит много других вещей. Но это чрезмерное упрощение. Для точного ответа вы можете предложить сценарий, зависящий от производительности.

person Lior    schedule 29.01.2011
comment
У меня есть 900 изображений, которые хотелось бы наложить на него .. Он работает отлично, но почему он очень медленный :( Это действительно занимает много времени - person Ahmad Arslan; 20.04.2015
comment
У меня IllegalArgumentException ... Там написано неизменяемое растровое изображение. - person Rahul Rastogi; 08.05.2015
comment
(Я знаю - старый комментарий. Но для других, кто может с ним столкнуться :) параметр bitmap должен быть изменяемым растровым изображением. Просмотрите эту запись в блоге, чтобы посмотреть, как преобразовать неизменяемое растровое изображение в изменяемое или загрузить файл в изменяемый. - person et_l; 22.01.2017

Если целью является получение растрового изображения, это очень просто:

Canvas canvas = new Canvas();
canvas.setBitmap(image);
canvas.drawBitmap(image2, new Matrix(), null);

В конце концов, изображение будет содержать перекрытие изображения и изображения2.

person Giorgio Barchiesi    schedule 19.10.2012

Думаю, этот пример определенно поможет вам наложить прозрачное изображение поверх другого изображения. Это стало возможным благодаря рисованию изображений на холсте и возврату растрового изображения.

Узнайте больше или загрузите демо здесь

private Bitmap createSingleImageFromMultipleImages(Bitmap firstImage, Bitmap secondImage){

        Bitmap result = Bitmap.createBitmap(firstImage.getWidth(), firstImage.getHeight(), firstImage.getConfig());
        Canvas canvas = new Canvas(result);
        canvas.drawBitmap(firstImage, 0f, 0f, null);
        canvas.drawBitmap(secondImage, 10, 10, null);
        return result;
    }

и вызовите указанную выше функцию нажатием кнопки и передайте два изображения нашей функции, как показано ниже.

public void buttonMerge(View view) {

        Bitmap bigImage = BitmapFactory.decodeResource(getResources(), R.drawable.img1);
        Bitmap smallImage = BitmapFactory.decodeResource(getResources(), R.drawable.img2);
        Bitmap mergedImages = createSingleImageFromMultipleImages(bigImage, smallImage);

        img.setImageBitmap(mergedImages);
    }

Для более чем двух изображений вы можете перейти по этой ссылке как программно объединить несколько изображений на android

person Daniel Nyamasyo    schedule 19.12.2016

Для поклонников Котлина:

  1. Вы можете создать более общее расширение:
 private fun Bitmap.addOverlay(@DimenRes marginTop: Int, @DimenRes marginLeft: Int, overlay: Bitmap): Bitmap? {
        val bitmapWidth = this.width
        val bitmapHeight = this.height
        val marginLeft = shareBitmapWidth - overlay.width - resources.getDimension(marginLeft)
        val finalBitmap = Bitmap.createBitmap(bitmapWidth, bitmapHeight, this
            .config)

        val canvas = Canvas(finalBitmap)
        canvas.drawBitmap(this, Matrix(), null)
        canvas.drawBitmap(overlay, marginLeft, resources.getDimension(marginTop), null)
        return finalBitmap
    }

  1. Затем используйте его следующим образом:
 bitmap.addOverlay( R.dimen.top_margin, R.dimen.left_margin, overlayBitmap)
person Fab    schedule 11.12.2019