掩蔽(裁剪)帧中的图像
Posted
技术标签:
【中文标题】掩蔽(裁剪)帧中的图像【英文标题】:Masking(crop) image in frame 【发布时间】:2012-09-18 20:02:52 【问题描述】:有一个丰富的 UI 应用程序,我想在其中显示像这样复杂形状的图像
现在我想要的是按照蒙版图像裁剪我的图像,实际上 图像是动态的,可以从相机或图库(方形或矩形形状)导入,我希望该图像适合在我上面的布局框架中
所以只是想知道我是如何实现这一目标的?任何想法/提示欢迎
背景框面具
点赞this
【问题讨论】:
【参考方案1】:在更改蒙版图像并使用Xfermode
和Bitmap
时终于得到了解决方案
面具
ImageView mImageView= (ImageView)findViewById(R.id.imageview_id);
Bitmap original = BitmapFactory.decodeResource(getResources(),R.drawable.content_image);
Bitmap mask = BitmapFactory.decodeResource(getResources(),R.drawable.mask);
Bitmap result = Bitmap.createBitmap(mask.getWidth(), mask.getHeight(), Config.ARGB_8888);
Canvas mCanvas = new Canvas(result);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
mCanvas.drawBitmap(original, 0, 0, null);
mCanvas.drawBitmap(mask, 0, 0, paint);
paint.setXfermode(null);
mImageView.setImageBitmap(result);
mImageView.setScaleType(ScaleType.CENTER);
mImageView.setBackgroundResource(R.drawable.background_frame);
查看输出
来源可以找到here
【讨论】:
你好@hotveryspicy,感谢示例代码,它帮助很大。我面临一些问题,一些小提示对我来说会有很长的路要走。我想以绘制的一些多边形形状切割位图。我的位图切割成多边形,但裁剪位图的内容取自左上角,即原始位图的 0,0。我想要绘制多边形的下面的内容。 @Nidhi 你可以创建相同的缩放位图。 @hotveryspicy 谢谢你的回复。实际上我想做这里给出的同样的事情。 ***.com/questions/15969028/…。我的问题是裁剪位图是从左上角裁剪,即 0,0。不形成我指定的路径。我也放了代码。请指导我哪里出错了。 感谢@hotveryspicy,对于任何需要它的人,我做了一个简单的叉子,可以帮助将图像缩放到面具的大小:github.com/worker8/MaskImage/tree/master 要缩放蒙版以适应图像,我使用这一行:Bitmap resized = Bitmap.createScaledBitmap(mask, original.getWidth(), original.getHeight(), true);并使用 mCanvas.drawBitmap(original, 0, 0, null); mCanvas.drawBitmap(resized, 0, 0, paint);【参考方案2】:使用 Picasso 库和自定义转换更容易:
MaskTransformation.java:
* ORIGINAL:
* Copyright (C) 2015 Wasabeef
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package me.monori.example.utilities;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.drawable.Drawable;
import android.support.v4.content.ContextCompat;
import com.squareup.picasso.Transformation;
public class MaskTransformation implements Transformation
private static Paint mMaskingPaint = new Paint();
private Context mContext;
private int mMaskId;
static
mMaskingPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
/**
* @param maskId If you change the mask file, please also rename the mask file, or Glide will get
* the cache with the old mask. Because getId() return the same values if using the
* same make file name. If you have a good idea please tell us, thanks.
*/
public MaskTransformation(Context context, int maskId)
mContext = context.getApplicationContext();
mMaskId = maskId;
@Override public Bitmap transform(Bitmap source)
int width = source.getWidth();
int height = source.getHeight();
Bitmap result = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Drawable mask = getMaskDrawable(mContext, mMaskId);
Canvas canvas = new Canvas(result);
mask.setBounds(0, 0, width, height);
mask.draw(canvas);
canvas.drawBitmap(source, 0, 0, mMaskingPaint);
source.recycle();
return result;
@Override public String key()
return "MaskTransformation(maskId=" + mContext.getResources().getResourceEntryName(mMaskId)
+ ")";
public Drawable getMaskDrawable(Context context, int maskId)
Drawable drawable = ContextCompat.getDrawable(context, maskId);
if (drawable == null)
throw new IllegalArgumentException("maskId is invalid");
return drawable;
然后简单地在一行中定义它:
Picasso.with(context)
.load(imageUrl)
.transform(new MaskTransformation(context, _maskDrawableId))
.placeholder(R.drawable.drawableId)
.into(imageView);
【讨论】:
【参考方案3】: final ImageView mImageView = (ImageView) findViewById(R.id.image);
mImageView.setBackgroundResource(R.drawable.user_outer_circle_icon);
mImageView.setOnClickListener(new OnClickListener()
@Override
public void onClick(View v)
if(b)
mImageView.setBackgroundResource(R.drawable.profil_circle);
Bitmap original = BitmapFactory.decodeResource(getResources(),R.drawable.doge);
Bitmap mask = BitmapFactory.decodeResource(getResources(),R.drawable.mask_white);
Bitmap mask1 = BitmapFactory.decodeResource(getResources(),R.drawable.pencil_bg);
original = Bitmap.createScaledBitmap(original, mask.getWidth(),mask.getHeight(), true);
Bitmap result = Bitmap.createBitmap(mask.getWidth(), mask.getHeight(),Config.ARGB_8888);
Canvas mCanvas = new Canvas(result);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
mCanvas.drawBitmap(original, 0, 0, null);
mCanvas.drawBitmap(mask, 0, 0, paint);
mCanvas.drawBitmap(mask1, 0, 0, null);
Bitmap mask2 = BitmapFactory.decodeResource(getResources(), R.drawable.ic_pencil);
mCanvas.drawBitmap(mask2, 0, 0, null);
mImageView.setImageBitmap(result);
mImageView.setScaleType(ScaleType.FIT_XY);
b=false;
else
ImageView mImageView = (ImageView) findViewById(R.id.image);
Bitmap original = BitmapFactory.decodeResource(getResources(),
R.drawable.doge);
Bitmap mask = BitmapFactory.decodeResource(getResources(),
R.drawable.mask_white);
original = Bitmap.createScaledBitmap(original, mask.getWidth(),
mask.getHeight(), true);
Bitmap result = Bitmap.createBitmap(mask.getWidth(), mask.getHeight(),
Config.ARGB_8888);
Canvas mCanvas = new Canvas(result);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
mCanvas.drawBitmap(original, 0, 0, null);
mCanvas.drawBitmap(mask, 0, 0, paint);
paint.setXfermode(null);
mImageView.setImageBitmap(result);
mImageView.setScaleType(ScaleType.FIT_XY);
// mImageView.setBackgroundResource(R.drawable.user_outer_circle_icon);
b= true;
);
【讨论】:
【参考方案4】:这个例子用掩码“animation_mask”屏蔽了他的子元素(Imageview)
<com.christophesmet.android.views.maskableframelayout.MaskableFrameLayout
android:id="@+id/frm_mask_animated"
android:layout_
app:porterduffxfermode="DST_IN"
app:mask="@drawable/animation_mask"
android:layout_>
<ImageView android:layout_
android:layout_
android:scaleType="centerCrop"
android:src="@drawable/unicorn"/>
check this git link
【讨论】:
以上是关于掩蔽(裁剪)帧中的图像的主要内容,如果未能解决你的问题,请参考以下文章
如何将视频文件作为输入传递给 NodeJS 中的子进程并接收帧/图像作为输出?