如何剪辑一个星机器人?但是,明星的出现很明显 [英] How to Clip a Star in android ? But the appearance of the star is clear

查看:151
本文介绍了如何剪辑一个星机器人?但是,明星的出现很明显的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

先来看看下面的图片。

package com.syncfusion.rating;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Region;
import android.view.View;
/**
 * Created by chozarajan.pandiyarajan on 10/9/2015.
 */

public class SfRatingItem extends View {

private   int fillColor,minDim,topXPoint,topYPoint;
private double bigHypot,bigA,bigB,littleHypot,littleA,littleB,value;
private  Paint starPaint;
private Path path;

public SfRatingItem(Context context) {
    super(context);
    starPaint=new Paint();
    fillPaint=new Paint();
    path = new Path();
}
@Override
protected void onDraw(Canvas canvas) {
    starPaint.setStyle(Paint.Style.FILL_AND_STROKE);
    starPaint.setAntiAlias(true);

    minDim = Math.min(this.getWidth() - this.getPaddingLeft() -this.getPaddingRight(), this.getHeight() - this.getPaddingTop() - this.getPaddingBottom());

    bigHypot = (minDim / Math.cos(Math.toRadians(18)));
    bigB = minDim;
    bigA = Math.tan(Math.toRadians(18)) * bigB;

    littleHypot = bigHypot / (2 + Math.cos(Math.toRadians(72)) + Math.cos(Math.toRadians(72)));
    littleA = Math.cos(Math.toRadians(72)) * littleHypot;
    littleB = Math.sin(Math.toRadians(72)) * littleHypot;

    topXPoint = (this.getWidth() - this.getPaddingLeft() -this.getPaddingRight()) / 2;
    topYPoint =this.getPaddingTop();

    path.moveTo(topXPoint, topYPoint);
    path.lineTo((int) (topXPoint + bigA), (int) (topYPoint + bigB));
    path.lineTo((int) (topXPoint - littleA - littleB), (int) (topYPoint + littleB));
    path.lineTo((int) (topXPoint + littleA + littleB), (int) (topYPoint + littleB));
    path.lineTo((int) (topXPoint - bigA), (int) (topYPoint + bigB));
    path.lineTo(topXPoint, topYPoint);
    path.close();
    starPaint.setColor(Color.RED); 

 //Use below code to paint the star
 canvas.drawPath(path, starPaint);

 // Use below code to clip the star path.
     // canvas.clipPath(path, Region.Op.DIFFERENCE);
     //  canvas.drawColor(Color.WHITE);
    super.onDraw(canvas);
 } 

如果你看到上面的图片,你就知道这两个图像的差异。

If you see the above images, you know the difference of this two images.

第一个是切出图像。边的裁剪星不明确。

First one is clipped image. The clipped star of the edges is not clear.

二是手绘的图像。边的绘星是明确的。

Second one is Painted image. The painted star of the edges are clear.

由于画中的形象,我用它来设置setAntiAlise真正的()属性。

Because in painted image, i am use to set true of setAntiAlise() property.

我的问题是如何获得的截取图像边缘清楚了吗?

My question is how to get the clipped image edges are clear?

推荐答案

看来你不能用 clipPath 执行抗锯齿。而不是使用 clipPath 进行屏蔽,尽量位掩码(这是一个比较复杂一点的 clipPath ,但它给出了明确边缘的恒星)。我修改了code使用位图掩盖,而不是夹路径。

It seems that you can't perform Anti Aliasing with clipPath. Instead of using clipPath for masking, try bitmap masking (it's a bit more complicated that clipPath, but it gives a clear edges for the star). I have modified your code to use bitmap masking instead of clip path.

code:

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;

/**
 * Created by chozarajan.pandiyarajan on 10/9/2015.
 */

public class SfRatingItem extends View {

    private int fillColor, minDim, topXPoint, topYPoint;
    private double bigHypot, bigA, bigB, littleHypot, littleA, littleB, value;
    private Paint starPaint;
    private Path path;
    private Bitmap starBitmap;
    private Bitmap backBitmap;

    public SfRatingItem(Context context, AttributeSet attrs) {
        super(context, attrs);
        initialize();
    }

    public SfRatingItem(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initialize();
    }

    public SfRatingItem(Context context) {
        super(context);
        initialize();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        initialDraw();
        Paint q = new Paint(Paint.ANTI_ALIAS_FLAG);

        //canvas.saveLayer(0,0,canvas.getWidth(),canvas.getHeight(),q); // expensive call, instead set a hardware layer
        setLayerType(LAYER_TYPE_HARDWARE, q);

        canvas.drawBitmap(backBitmap, 0, 0, q);
        q.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
        canvas.drawBitmap(starBitmap, 0, 0, q);
        q.setXfermode(null);

    }

    private void initialDraw() {
        starPaint.setStyle(Paint.Style.FILL_AND_STROKE);
        starPaint.setAntiAlias(true);

        minDim = Math.min(this.getWidth() - this.getPaddingLeft() - this.getPaddingRight(), this.getHeight() - this.getPaddingTop() - this.getPaddingBottom());

        bigHypot = (minDim / Math.cos(Math.toRadians(18)));
        bigB = minDim;
        bigA = Math.tan(Math.toRadians(18)) * bigB;

        littleHypot = bigHypot / (2 + Math.cos(Math.toRadians(72)) + Math.cos(Math.toRadians(72)));
        littleA = Math.cos(Math.toRadians(72)) * littleHypot;
        littleB = Math.sin(Math.toRadians(72)) * littleHypot;

        topXPoint = (this.getWidth() - this.getPaddingLeft() - this.getPaddingRight()) / 2;
        topYPoint = this.getPaddingTop();

        path.moveTo(topXPoint, topYPoint);
        path.lineTo((int) (topXPoint + bigA), (int) (topYPoint + bigB));
        path.lineTo((int) (topXPoint - littleA - littleB), (int) (topYPoint + littleB));
        path.lineTo((int) (topXPoint + littleA + littleB), (int) (topYPoint + littleB));
        path.lineTo((int) (topXPoint - bigA), (int) (topYPoint + bigB));
        path.lineTo(topXPoint, topYPoint);
        path.close();

        // Draw the STAR mask in a bitmap
        RectF bounds = new RectF();
        path.computeBounds(bounds, true);
        starBitmap = Bitmap.createBitmap((int) bounds.width(), (int) bounds.height(), Bitmap.Config.ARGB_8888);
        Canvas starCanvas = new Canvas(starBitmap);
        starPaint.setColor(Color.BLACK);
        starCanvas.drawPath(path, starPaint);

        // Draw the background rectangle in a bitmap
        starPaint.setColor(Color.RED);
        backBitmap = Bitmap.createBitmap((int) bounds.width(), (int) bounds.height(), Bitmap.Config.ARGB_8888);
        Canvas backCanvas = new Canvas(backBitmap);
        final Rect backRect = new Rect(0, 0, backBitmap.getWidth(), backBitmap.getHeight());
        backCanvas.drawRect(backRect, starPaint);
    }

    private void initialize() {
        starPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        path = new Path();
    }
}

在这里,我创建了两个位图,一个明星面具,另一个用于矩形背景。然后,使用 Paint.setXfermode(),我掩​​盖一个位图比其他。您可以动态显示部分填充通过修改后台矩形的宽度(即宽度 backRect 的)。目前,我创建了的OnDraw()法的位图,但是这是一个坏主意,你需要做的`构造本身的基础上的大小明星必需的。

Here I have created two bitmaps, one for the star mask and the other for the background rectangle. Then using Paint.setXfermode(), I have masked one bitmap over the other. You can dynamically show the partial filling by modifying the width of the background rectangle (i.e, width of backRect). Currently I am creating the bitmaps in the onDraw() method, but this is a bad idea and you need to do this in the `constructor itself, based on the size of the star required.

这篇关于如何剪辑一个星机器人?但是,明星的出现很明显的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆