2010-04-29 16 views
93

Estoy tratando de superponer dos imágenes en mi aplicación, pero parecen bloquearse en mi línea canvas.setBitmap(). ¿Qué estoy haciendo mal?superposición de dos imágenes en android para establecer una imagen vista

private void test() { 
    Bitmap mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.t); 
    Bitmap mBitmap2 = BitmapFactory.decodeResource(getResources(), R.drawable.tt); 
    Bitmap bmOverlay = Bitmap.createBitmap(mBitmap.getWidth(), mBitmap.getHeight(), mBitmap.getConfig()); 
    Canvas canvas = new Canvas(); 
    canvas.setBitmap(bmOverlay); 
    canvas.drawBitmap(mBitmap, new Matrix(), null); 
    canvas.drawBitmap(mBitmap2, new Matrix(), null); 
    testimage.setImageBitmap(bmOverlay); 
} 
+0

puede utilizar un FrameLayout así, como este: http://stackoverflow.com/a/11658554/586484 – Lysogen

Respuesta

228

Puede omitir la manipulación lienzo complejo y hacerlo en su totalidad con dibujables, utilizando LayerDrawable. Tiene una de dos opciones: puede define it in XML y luego simplemente configurar la imagen, o puede configurar LayerDrawable dinámicamente en el código.

Solución # 1 (vía XML):

Crear un nuevo archivo XML Disponibles, vamos a llamarlo layer.xml:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> 
    <item android:drawable="@drawable/t" /> 
    <item android:drawable="@drawable/tt" /> 
</layer-list> 

Ahora ajustar la imagen utilizando ese Disponibles:

testimage.setImageDrawable(getResources().getDrawable(R.layout.layer)); 

Solución n. ° 2 (dinámica):

Resources r = getResources(); 
Drawable[] layers = new Drawable[2]; 
layers[0] = r.getDrawable(R.drawable.t); 
layers[1] = r.getDrawable(R.drawable.tt); 
LayerDrawable layerDrawable = new LayerDrawable(layers); 
testimage.setImageDrawable(layerDrawable); 

(No he probado este código por lo que puede haber un error, pero este esquema general debería funcionar.)

+1

gracias, funcionó! un error tipográfico aunque, en caso de que alguien más use el código: capas LayerDrawable2 = new LayerDrawable (capas); testimage.setImageDrawable (layers2); – John

+5

lo siento, debe haberlo editado poco después de que agarré el código – John

+1

Excelente manera de ahorrar espacio y reutilizar imágenes. Además, puedes usar el android: left, android: right, android: top y android: down para controlar la posición de una de las capas en el archivo .xml. – zabawaba99

8

bien solo para que sepa que hay un programa que se llama DroidDraw. Puede ayudarte a dibujar objetos y probarlos uno encima del otro. Probé tu solución pero tenía animación debajo de la imagen más pequeña, así que no funcionó. Pero luego traté de colocar una imagen en una disposición relativa que se supone que debe estar debajo de la primera y luego, sobre ella, dibujé la otra imagen que se supone que se superpone y todo funcionó de maravilla. Así que RelativeLayout, DroidDraw y eres bueno ir :) Simple, no hay ningún tipo de jodgery pockery :) y aquí hay un poco de código para ti:

El logotipo estará sobre la imagen de fondo de shazam.

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout 
android:id="@+id/widget30" 
android:layout_width="fill_parent" 
android:layout_height="fill_parent" 
xmlns:android="http://schemas.android.com/apk/res/android" 
> 
<ImageView 
android:id="@+id/widget39" 
android:layout_width="219px" 
android:layout_height="225px" 
android:src="@drawable/shazam_bkgd" 
android:layout_centerVertical="true" 
android:layout_centerHorizontal="true" 
> 
</ImageView> 
<ImageView 
android:id="@+id/widget37" 
android:layout_width="wrap_content" 
android:layout_height="wrap_content" 
android:src="@drawable/shazam_logo" 
android:layout_centerVertical="true" 
android:layout_centerHorizontal="true" 
> 
</ImageView> 
</RelativeLayout> 
2

Es una respuesta poco tarde, pero cubre la fusión de imágenes de URLs usando Picasso

MergeImageView

import android.annotation.TargetApi; 
import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.os.AsyncTask; 
import android.os.Build; 
import android.util.AttributeSet; 
import android.util.SparseArray; 
import android.widget.ImageView; 
import com.squareup.picasso.Picasso; 

import java.io.IOException; 
import java.util.List; 

public class MergeImageView extends ImageView { 

    private SparseArray<Bitmap> bitmaps = new SparseArray<>(); 
    private Picasso picasso; 
    private final int DEFAULT_IMAGE_SIZE = 50; 
    private int MIN_IMAGE_SIZE = DEFAULT_IMAGE_SIZE; 
    private int MAX_WIDTH = DEFAULT_IMAGE_SIZE * 2, MAX_HEIGHT = DEFAULT_IMAGE_SIZE * 2; 
    private String picassoRequestTag = null; 

    public MergeImageView(Context context) { 
     super(context); 
    } 

    public MergeImageView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    public MergeImageView(Context context, AttributeSet attrs, int defStyleAttr) { 
     super(context, attrs, defStyleAttr); 
    } 

    @TargetApi(Build.VERSION_CODES.LOLLIPOP) 
    public MergeImageView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 
     super(context, attrs, defStyleAttr, defStyleRes); 
    } 

    @Override 
    public boolean isInEditMode() { 
     return true; 
    } 

    public void clearResources() { 
     if (bitmaps != null) { 
      for (int i = 0; i < bitmaps.size(); i++) 
       bitmaps.get(i).recycle(); 
      bitmaps.clear(); 
     } 
     // cancel picasso requests 
     if (picasso != null && AppUtils.ifNotNullEmpty(picassoRequestTag)) 
      picasso.cancelTag(picassoRequestTag); 
     picasso = null; 
     bitmaps = null; 
    } 

    public void createMergedBitmap(Context context, List<String> imageUrls, String picassoTag) { 
     picasso = Picasso.with(context); 
     int count = imageUrls.size(); 
     picassoRequestTag = picassoTag; 

     boolean isEven = count % 2 == 0; 
     // if url size are not even make MIN_IMAGE_SIZE even 
     MIN_IMAGE_SIZE = DEFAULT_IMAGE_SIZE + (isEven ? count/2 : (count/2) + 1); 
     // set MAX_WIDTH and MAX_HEIGHT to twice of MIN_IMAGE_SIZE 
     MAX_WIDTH = MAX_HEIGHT = MIN_IMAGE_SIZE * 2; 
     // in case of odd urls increase MAX_HEIGHT 
     if (!isEven) MAX_HEIGHT = MAX_WIDTH + MIN_IMAGE_SIZE; 

     // create default bitmap 
     Bitmap bitmap = Bitmap.createScaledBitmap(BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_wallpaper), 
       MIN_IMAGE_SIZE, MIN_IMAGE_SIZE, false); 

     // change default height (wrap_content) to MAX_HEIGHT 
     int height = Math.round(AppUtils.convertDpToPixel(MAX_HEIGHT, context)); 
     setMinimumHeight(height * 2); 

     // start AsyncTask 
     for (int index = 0; index < count; index++) { 
      // put default bitmap as a place holder 
      bitmaps.put(index, bitmap); 
      new PicassoLoadImage(index, imageUrls.get(index)).execute(); 
      // if you want parallel execution use 
      // new PicassoLoadImage(index, imageUrls.get(index)).(AsyncTask.THREAD_POOL_EXECUTOR); 
     } 
    } 

    private class PicassoLoadImage extends AsyncTask<String, Void, Bitmap> { 

     private int index = 0; 
     private String url; 

     PicassoLoadImage(int index, String url) { 
      this.index = index; 
      this.url = url; 
     } 

     @Override 
     protected Bitmap doInBackground(String... params) { 
      try { 
       // synchronous picasso call 
       return picasso.load(url).resize(MIN_IMAGE_SIZE, MIN_IMAGE_SIZE).tag(picassoRequestTag).get(); 
      } catch (IOException e) { 
      } 
      return null; 
     } 

     @Override 
     protected void onPostExecute(Bitmap output) { 
      super.onPostExecute(output); 
      if (output != null) 
       bitmaps.put(index, output); 

      // create canvas 
      Bitmap.Config conf = Bitmap.Config.RGB_565; 
      Bitmap canvasBitmap = Bitmap.createBitmap(MAX_WIDTH, MAX_HEIGHT, conf); 
      Canvas canvas = new Canvas(canvasBitmap); 
      canvas.drawColor(Color.WHITE); 

      // if height and width are equal we have even images 
      boolean isEven = MAX_HEIGHT == MAX_WIDTH; 
      int imageSize = bitmaps.size(); 
      int count = imageSize; 

      // we have odd images 
      if (!isEven) count = imageSize - 1; 
      for (int i = 0; i < count; i++) { 
       Bitmap bitmap = bitmaps.get(i); 
       canvas.drawBitmap(bitmap, bitmap.getWidth() * (i % 2), bitmap.getHeight() * (i/2), null); 
      } 
      // if images are not even set last image width to MAX_WIDTH 
      if (!isEven) { 
       Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmaps.get(count), MAX_WIDTH, MIN_IMAGE_SIZE, false); 
       canvas.drawBitmap(scaledBitmap, scaledBitmap.getWidth() * (count % 2), scaledBitmap.getHeight() * (count/2), null); 
      } 
      // set bitmap 
      setImageBitmap(canvasBitmap); 
     } 
    } 
} 

xml

<com.example.MergeImageView 
    android:id="@+id/iv_thumb" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" /> 

Ejemplo

List<String> urls = new ArrayList<>(); 
String picassoTag = null; 
// add your urls 
((MergeImageView)findViewById(R.id.iv_thumb)). 
     createMergedBitmap(MainActivity.this, urls,picassoTag); 
3

Usted puede utilizar el código siguiente para resolver el problema o download demo here

Cree dos funciones para manejar cada uno.

En primer lugar, el lienzo se dibuja y las imágenes se dibujan en la parte superior de uno al otro desde el punto (0,0)

El botón de clic

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

función para crear una superposición.

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 buttonClick(View view){ 

}

Read more

Cuestiones relacionadas