Android - 具有不同位图和TileMode

时间:2016-05-13 17:13:50

标签: android image bitmap shader android-canvas

我目前面临Android的BitmapShader问题。 基本上,我想建立一个图像圈,其中每个图像都被圈在圆的部分弧上 以下是帮助的例子: enter image description here

我已经成功地将图像掩盖到每个部分弧中,但结果并不令人满意。我尝试了两种不同的BitmapShader模式:CLAMP和REPEAT模式。

enter image description here

BitmapShader的CLAMP模式似乎在不同的BitmapShader之间共享,即使使用不同的Paint对象 这是REPEAT模式 enter image description here

与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模式,它会给我一个非常困难的时间来计算每个图像使用局部矩阵的平移,因为平铺线穿过不同的着色器。

我很欣赏任何给出的答案。提前谢谢

0 个答案:

没有答案