我目前面临Android的BitmapShader问题。
基本上,我想建立一个图像圈,其中每个图像都被圈在圆的部分弧上
以下是帮助的例子:
我已经成功地将图像掩盖到每个部分弧中,但结果并不令人满意。我尝试了两种不同的BitmapShader模式:CLAMP和REPEAT模式。
BitmapShader的CLAMP模式似乎在不同的BitmapShader之间共享,即使使用不同的Paint对象
这是REPEAT模式
与CLAMP类似,平铺属性在不同的BitmapShaders之间共享,尽管我使用了不同的Paint和Bitmap对象
这是源代码:
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;
}
}
}
我想要实现的是CLAMP模式,但没有边缘复制属性与其他BitmapShader或REPEAT模式共享,但是能够获得所显示的裁剪图像的中心部分(而不是部分)显示平铺的地方)。我一直在摸不着头脑,但没有一个我能想到的解决方案。
另外,我想知道如何从图像中心制作BitmapShader蒙版。如果我使用REPEAT模式,它会给我一个非常困难的时间来计算每个图像使用局部矩阵的平移,因为平铺线穿过不同的着色器。
我很欣赏任何给出的答案。提前谢谢