Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/199.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android-具有不同位图和TileMode的多个位图着色器_Android_Image_Bitmap_Shader_Android Canvas - Fatal编程技术网

Android-具有不同位图和TileMode的多个位图着色器

Android-具有不同位图和TileMode的多个位图着色器,android,image,bitmap,shader,android-canvas,Android,Image,Bitmap,Shader,Android Canvas,我目前面临android的BitmapShader问题。 基本上,我想建立一个图像圆,其中每个图像都被遮罩在圆的部分圆弧上 下面是有帮助的插图: 我已经设法将图像遮罩到每个部分弧中,但结果并不令人满意。我尝试了BitmapShader的两种不同模式:钳制模式和重复模式 BitmapShader的钳制模式似乎在不同的BitmapShader之间共享,即使使用不同的绘制对象也是如此 这是重复模式 与CLAMP类似,尽管我使用了不同的绘制和位图对象,但平铺属性在不同的位图着色器之间共享 以下是源

我目前面临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()方法,我可以轻松地设置遮罩图像在遮罩内的位置。感谢您提供的解决方案。我会试试这个,看看我能做些什么