Android-具有不同位图和TileMode的多个位图着色器
我目前面临android的BitmapShader问题。 基本上,我想建立一个图像圆,其中每个图像都被遮罩在圆的部分圆弧上 下面是有帮助的插图: 我已经设法将图像遮罩到每个部分弧中,但结果并不令人满意。我尝试了BitmapShader的两种不同模式:钳制模式和重复模式 BitmapShader的钳制模式似乎在不同的BitmapShader之间共享,即使使用不同的绘制对象也是如此 这是重复模式 与CLAMP类似,尽管我使用了不同的绘制和位图对象,但平铺属性在不同的位图着色器之间共享 以下是源代码:Android-具有不同位图和TileMode的多个位图着色器,android,image,bitmap,shader,android-canvas,Android,Image,Bitmap,Shader,Android Canvas,我目前面临android的BitmapShader问题。 基本上,我想建立一个图像圆,其中每个图像都被遮罩在圆的部分圆弧上 下面是有帮助的插图: 我已经设法将图像遮罩到每个部分弧中,但结果并不令人满意。我尝试了BitmapShader的两种不同模式:钳制模式和重复模式 BitmapShader的钳制模式似乎在不同的BitmapShader之间共享,即使使用不同的绘制对象也是如此 这是重复模式 与CLAMP类似,尽管我使用了不同的绘制和位图对象,但平铺属性在不同的位图着色器之间共享 以下是源
public class CustomMasking extends RelativeLayout {
//images. all of them are 150x150 in size
private static final int[] IMAGES = {
R.drawable.img1, R.drawable.img2, R.drawable.img3, R.drawable.img4,
R.drawable.img5, R.drawable.img6
};
//array of the masked bitmaps
private MaskedBitmap[] maskedBitmaps;
private RectF innerCircle, outerCircle;
//angles and dimensions. centerX and centerY is the center coord of circle
private float angle;
private int centerX=300, centerY=400;
private int innerRadius=150, outerRadius=300;
//paint strokes for debug draw
private Paint redstroke;
public CustomMasking(Context c, AttributeSet set){
super(c,set);
this.setWillNotDraw(false);
//setup paint to debug draw
redstroke = new Paint();
redstroke.setStyle(Paint.Style.STROKE);
redstroke.setColor(Color.RED);
redstroke.setStrokeWidth(3);
innerCircle = new RectF(
centerX-innerRadius,centerY-innerRadius,
centerX+innerRadius,centerY+innerRadius
); //inner circle with radius=150
outerCircle = new RectF(
centerX-outerRadius,centerY-outerRadius,
centerX+outerRadius,centerY+outerRadius
); //outer circle with radius=300
//calculate angle
angle = 360f/IMAGES.length;
//load image and setup mask
maskedBitmaps = new MaskedBitmap[IMAGES.length];
for (int i = 0 ; i < IMAGES.length ; i++){
maskedBitmaps[i] = new MaskedBitmap(IMAGES[i]);
maskedBitmaps[i].setPath(createPartialArc(i*angle, angle));
}
}
//method returns a partial arc from 'angle' to 'angle+sweep'
private Path createPartialArc(float angle, float sweep){
Path p = new Path();
p.arcTo(outerCircle,angle,sweep);
p.arcTo(innerCircle,angle+sweep,-sweep);
p.close();
return p;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
for (int i = 0 ; i < maskedBitmaps.length ; i++){
MaskedBitmap mbmp = maskedBitmaps[i];
//draw the red stroke
canvas.drawPath(mbmp.getPath(), redstroke);
//draw the masked image
canvas.drawPath(mbmp.getPath(), mbmp.getPaint());
}
}
//custom class to create the shader, etc.
private class MaskedBitmap{
private Bitmap bmp;
private BitmapShader shader;
private Paint paint;
private Path path;
public MaskedBitmap(int drawableResId){
bmp = BitmapFactory.decodeResource(getResources(), drawableResId);
//The screenshots available are on REPEAT and CLAMP modes
shader = new BitmapShader(bmp, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
paint = new Paint();
paint.setShader(shader);
paint.setAntiAlias(true);
paint.setFilterBitmap(true);
path = null;
}
public Paint getPaint(){
return paint;
}
public Path getPath(){
return path;
}
public void setPath(Path p){
this.path = p;
}
}
公共类CustomMasking扩展了RelativeLayout{
//图像。所有图像的大小均为150x150
私有静态最终int[]图像={
R.drawable.img1,R.drawable.img2,R.drawable.img3,R.drawable.img4,
R.drawable.img5,R.drawable.img6
};
//蒙版位图数组
私有MaskedBitmap[]MaskedBitmap;
专用RectF内圆、外圆;
//角度和尺寸。centerX和centerY是圆的中心坐标
私人浮动角度;
专用int centerX=300,centerY=400;
私有内部半径=150,外部半径=300;
//为调试绘制绘制笔划
私人油漆红字;
公共自定义屏蔽(上下文c,属性集){
super(c,set);
此.setWillNotDraw(false);
//设置绘图以调试绘图
redstroke=新油漆();
redstroke.setStyle(画图、样式、笔划);
redstroke.setColor(Color.RED);
红色行程。设置行程宽度(3);
innerCircle=新的RectF(
中心X内半径,中心Y内半径,
centerX+内半径,centerY+内半径
);//半径为150的内圈
outerCircle=新的RectF(
centerX outerRadius,centerY outerRadius,
centerX+outerRadius,centerY+outerRadius
);//半径为300的外圆
//计算角度
角度=360f/图像长度;
//加载图像和设置掩码
maskedBitmaps=新的MaskedBitmap[IMAGES.length];
对于(int i=0;i
}
我想要实现的是钳制模式,但没有与其他BitmapShader共享的边缘复制属性,或者重复模式,但能够获得显示的裁剪图像的中心部分(而不是显示平铺的部分)。我绞尽脑汁已经一天了,但我想不出任何解决办法
另外,我想知道如何从图像中心制作BitmapShader遮罩。如果我使用重复模式,使用局部矩阵计算每个图像的平移会非常困难,因为平铺线穿过不同的着色器
如果您能给我答复,我将不胜感激。提前谢谢你这是因为你所有的R.drawable.img*。如果尺寸相同,试着放大其中一些,你会看到不同之处。我试着用钳制模式放大图像。如果图像的尺寸实际上大于遮罩的尺寸,则该方法有效。问题是,BitmapShader仅遮罩图像的左上部分。如果我知道如何使用局部矩阵将它们居中,我会选择此解决方案使用@pksink hmm REPEAT。通过使用computeBounds()方法,我可以轻松地设置遮罩图像在遮罩内的位置。感谢您提供的解决方案。我会试试这个,看看我能做些什么