安卓 - 是否可以直接在图层列表(layer-list)XML定义中声明alpha遮罩?

32

一个新手问题

我有一个名为layers.xml的文件,我将其用作ImageView的源。 这个文件使用两个图片:mask.png和image.jpg。

layers.xml:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <bitmap  android:src="@drawable/image" android:gravity="center"/>
    </item>
    <item>
        <bitmap  android:src="@drawable/mask" android:gravity="center"/>
    </item>
</layer-list>

ImageView:

<ImageView
 android:id="@+id/img_B"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent"
 android:src="@drawable/layers"/>

目前输出只是将PNG图像放置在另一个图像之上。我希望该PNG图像能够作为蒙版,使用其alpha通道剪裁图像,如下所示: enter image description here

这是否可以直接在xml中实现,还是必须通过代码完成?

谢谢您的建议;)

更新: 目前,我通过使用代码替换整个ImageView来实现了我的目标。

ImageView img = (ImageView) findViewById(imgID);

Canvas canvas = new Canvas();
Bitmap mainImage = BitmapFactory.decodeResource(getResources(), R.drawable.img);
Bitmap mask = BitmapFactory.decodeResource(getResources(), R.drawable.mask);
Bitmap result = Bitmap.createBitmap(mainImage.getWidth(), mainImage.getHeight(), Bitmap.Config.ARGB_8888);

canvas.setBitmap(result);
Paint paint = new Paint();
paint.setFilterBitmap(false);

canvas.drawBitmap(mainImage, 0, 0, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
canvas.drawBitmap(mask, 0, 0, paint);
paint.setXfermode(null);

img.setImageBitmap(result);
img.invalidate();

1
这是一个很好的指引!虽然我不确定,但让我看看并回复您。 - Shaunak
2
你必须将这个设为接受答案,因为它刚刚救了我! - DeeV
给出的答案并没有回答原始问题,我仍然想知道是否可以使用layer-list xml声明遮罩层。 - Shlomi Schwartz
2个回答

7

将你的口罩图像放在drawable-nodpi文件夹中。

否则,缩放比例将不正确。

这是应用程序中的一些示例代码。在相机之后,它添加一个口罩。

public void onActivityResult(int requestCode, int resultCode, Intent data)
  {
  if (requestCode == REQUEST_IMAGE_CAPTURE) // && resultCode == RESULT_OK )
    {

    try
      {
      Bitmap cameraBmp = MediaStore.Images.Media.getBitmap(
          State.mainActivity.getContentResolver(),
          Uri.fromFile(Utils.tempFileForAnImage())
                                );

      cameraBmp = ThumbnailUtils.extractThumbnail(cameraBmp, 256, 256);

      Matrix m = new Matrix();
      m.postRotate(Utils.neededRotation(Utils.tempFileForAnImage()));
      // NOTE incredibly useful trick for cropping/resizing square
      // https://dev59.com/Cmw05IYBdhLWcg3w_Guw#17733530

      cameraBmp = Bitmap.createBitmap(cameraBmp,
          0, 0, cameraBmp.getWidth(), cameraBmp.getHeight(),
          m, true);


      // so, cameraBmp is now a Bitmap.  Let's add the mask!!
      // see Shiomi Schwartz's original!! https://dev59.com/xmoy5IYBdhLWcg3wUcb_

      Bitmap mask = BitmapFactory.decodeResource(
            getResources(),
            R.drawable.mask_android_256);
      // NOTE THE MASK ** MUST ** BE IN YOUR nodpi folder

      Bitmap result = Bitmap.createBitmap( 256,256, Bitmap.Config.ARGB_8888);

      Canvas cc = new Canvas();
      cc.setBitmap(result);

      Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
      paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));

      cc.drawBitmap(cameraBmp, 0, 0, null);
      cc.drawBitmap(mask, 0,0, paint);

      // so, cameraBmp is now a Bitmap but it has been masked



      yourImageViewForTheUser.setImageBitmap(result);

      // make a "baos" ... we want PNG in this case ..
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      result.compress(Bitmap.CompressFormat.PNG, 0, baos);

      imageBytesRESULT = baos.toByteArray();
      // typically you want the result as image bytes, example to send to Parse

      } catch (FileNotFoundException e)
      {
      e.printStackTrace();
      } catch (IOException e)
      {
      e.printStackTrace();
      }

    return;
    }

  }

-1

.png文件在创建时可以包含一个alpha通道,Android可以使用它来隔离图像,正如您所解释的那样。

在GIMP、Photoshop或您使用的任何图像编辑器中创建一个额外的通道。这将是一个单色通道(256个白到黑的色阶)。选择要掩蔽的部分,点击alpha通道并用黑色填充选区。反转选择,仍在alpha通道中,并用白色填充。保存并导出.png文件为24位带透明度的图像(实际上是32位)。您的文件应该能够正确显示。


4
创建一个alpha通道图像很容易,我在询问如何使用这个alpha通道作为遮罩。 - Shlomi Schwartz
1
@Erik 顺便说一下,这不是一个问题 :D - Rahil Wazir

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接