0

My application takes an image from the camera, saves it and then displays it on an ImageView, but the next step is to place a circle on top of the displayed image when the user touches the screen, and then save the "modified image".

Kinda like a image editor if you wish, problem is I do not know where to begin with the image editing. I tried this

  @Override
public boolean onTouch(View v, MotionEvent event) {
    circleView.setVisibility(View.VISIBLE);
    circleView.setX(event.getX()-125);
    circleView.setY(event.getY()-125);

   try{
        Bitmap bitmap = Bitmap.createBitmap(relativeLayout.getWidth(),relativeLayout.getHeight(),Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        v.draw(canvas);

        mImageView.setImageBitmap(bitmap);
        FileOutputStream output = new FileOutputStream(Environment.getExternalStorageDirectory());

        bitmap.compress(Bitmap.CompressFormat.PNG,100,output);
        output.close();
    }catch(FileNotFoundException e){
        e.printStackTrace();
    }catch (IOException e){
        e.printStackTrace();
    }


    return true;
}//ENDOF onTouch

What can I do to save the image?

mrOak
  • 193
  • 3
  • 12

1 Answers1

1

It'd be helpful if you included a bit more information about what libraries and language you're using. From the @override I'll assume this is java on android?

As for how to create a circle - there are many techniques you could use and there are probably more than a few libraries that you can use to do this. However, we can keep it pretty simple by using functions on the Bitmap object's interface, namely getPixels and setPixels.

What you need to do is grab a rectangle of pixels in to pre-allocated buffer (using getPixels), then draw your circle in to this buffer and then write the buffer back using 'setPixels'. Here's a simple (although not exactly efficient) method for drawing a circle in the buffer you'd get from 'getPixels' in javaish pseudocode (untested):

//Return the distance between the point 'x1, y1' and 'x2, y2'
float distance(float x1, float y1, float x2, float y2)
{
    float dx = x2 - x1;
    float dy = y2 - y1;
    return Math.sqrt(dx * dx + dy * dy);
}

//draw a circle in the buffer of pixels contained in 'int [] pixels' 
//at position 'cx, cy' with the given radius and colour.
void drawCircle(int [] pixels, int stride, int height, float cx, float cy, float radius, int colour) 
{
    for (int y = 0; y < height; ++y) 
        for (int x = 0; x < stride; ++x) 
        {
            if (distance((float)x, (float)y, cx, cy) < radius)
               pixels[x + y * stride] = colour;
        }
}

This just asks the question, for each pixel, 'is the point 'x,y' inside the circle given by 'cx, cy, radius'?' and if it is, it draw a pixel. More efficient approaches might include a scanline rasteriser that steps through the left and right sides of the circle, removing the need to do a costly 'distance' calculation for each pixel.

However, this 'implicit surface' approach is quite flexible and you can achieve a lot of effects with it. Other options might be to copy a pre made circle bitmap instead of creating your own on the fly.

You could also blend the 'colour' based on the fractional value of 'distance - radius' to achieve anti-aliasing.

Luther
  • 1,786
  • 3
  • 21
  • 38