StackOverflowed
StackOverflowed

Reputation: 5975

Android - Trying to gradually fill a circle bottom to top

I'm trying to fill a round circle (transparent other than the outline of the circle) in an ImageView.

I have the code working:

public void setPercentage(int p) {
    if (this.percentage != p ) {
   this.percentage = p;
    this.invalidate();
   }
}
@Override public void onDraw(Canvas canvas) {
 Canvas tempCanvas;
        Paint paint;    
        Bitmap bmCircle = null;
        if (this.getWidth() == 0 || this.getHeight() == 0 ) 
            return ; // nothing to do
        mergedLayersBitmap = Bitmap.createBitmap(this.getWidth(), this.getHeight(), Bitmap.Config.ARGB_8888); 

        tempCanvas = new Canvas(mergedLayersBitmap);
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);

        paint.setStyle(Paint.Style.FILL_AND_STROKE);
        paint.setFilterBitmap(false);



        bmCircle = drawCircle(this.getWidth(), this.getHeight());

        tempCanvas.drawBitmap(bmCircle, 0, 0, paint);


        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));

        tempCanvas.clipRect(0,0, this.getWidth(), (int) FloatMath.floor(this.getHeight() - this.getHeight() * ( percentage/100)));
        tempCanvas.drawColor(0xFF660000, PorterDuff.Mode.CLEAR);  

        canvas.drawBitmap(mergedLayersBitmap, null, new RectF(0,0, this.getWidth(), this.getHeight()), new Paint());
        canvas.drawBitmap(mergedLayersBitmap, 0, 0, new Paint());

    }
  static Bitmap drawCircle(int w, int h) {
        Bitmap bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        Canvas c = new Canvas(bm);
        Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);

        p.setColor(drawColor);    
        c.drawOval(new RectF(0, 0, w, h), p);
        return bm;

    }

It kind of works. However, I have two issues: I run out of memory quickly and the GC goes crazy. How can I utilize the least amount of memory for this operation?

I know I Shouldn't be instantiating objects in onDraw, however I'm not sure where to draw then. Thank you.

Upvotes: 0

Views: 1515

Answers (2)

Kaps
Kaps

Reputation: 2355

in case if you want to see another solution (perhaps cleaner), look at this link, filling a circle gradually from bottom to top android

Upvotes: 2

WIllJBD
WIllJBD

Reputation: 6154

pseudo would look something like this.

    for each pixel inside CircleBitmap {

        if (pixel.y is < Yboundary && pixelIsInCircle(pixel.x, pixel.y)) {
           CircleBitmap .setPixel(x, y, Color.rgb(45, 127, 0));
        }
    }

that may be slow, but it would work, and the smaller the circle the faster it would go.

just know the basics, bitmap width and height, for example 256x256, the circles radius, and to make things easy make the circle centered at 128,128. then as you go pixel by pixel, check the pixels X and Y to see if it falls inside the circle, and below the Y limit line.

then just use:

    CircleBitmap .setPixel(x, y, Color.rgb(45, 127, 0));

edit: to speed things up, don't even bother looking at the pixels above the Y limit.

Upvotes: 2

Related Questions