Vignette in Android - android

So this is what I have for a vignette style effect in Android (image is a Bitmap):
public void vignette() {
float radius = (float) (image.getWidth()/1.5);
RadialGradient gradient = new RadialGradient(image.getWidth()/2, image.getHeight()/2, radius, Color.TRANSPARENT, Color.BLACK, Shader.TileMode.CLAMP);
Canvas canvas = new Canvas(image);
canvas.drawARGB(1, 0, 0, 0);
final Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(Color.BLACK);
paint.setShader(gradient);
final Rect rect = new Rect(0, 0, image.getWidth(), image.getHeight());
final RectF rectf = new RectF(rect);
canvas.drawRect(rectf, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(image, rect, rect, paint);
}
This "works" but there are a couple of problems. First of all, this is not really a vignette, it's just a gradient so you can see bits of the black going nearly all the way to the center rather than feathering out closer to the edges.
The RadialGradient used also only allows for setting the radius of a circle rather than an ellipse. An ellipse would be able to more effectively match the dimensions of a non-square image than a circle.
The quality of the gradient is also not superb.
I'm trying to replicate the vignetteImage method from ImageMagick (I'm referring specifically to the php version). I have this code in PHP that produces the style of image that I want:
$im = new IMagick('city.png');
$im->vignetteImage($width/1.5, 350, 20, 20);
I've tried building ImageMagick with the NDK but have been unsuccessful in properly linking the various image libraries (I've only successfully built with gif support but no png, jpeg or tiff).
I've also attached an image comparing the two methods shown above. The image on the left was generated with ImageMagick through php and the image on the right was generated using the method shown above for Android.

If you look carefully at the image on left, tf uses exponential increase in Alpha (transparency) vs. image on right which is very linear.
Clearly Shader.TitleMode.CLAMP is a linear function. What you should do instead is use RadialGradient(float x, float y, float radius, int[] colors, float[] positions, Shader.TileMode tile) to define 10 or more points on the image with exponentially decreasing color values (black to transparent).
Alternatively, you can refer gallery 3d source for ICS gallery http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android-apps/4.0.1_r1/com/android/gallery3d/photoeditor/filters/VignetteFilter.java?av=h

I know this is an old discussion but it may help someone.
You can use AccelerateInterpolator to generate the points that Taranfx had mentioned and it will lock awesome.

Related

clipping semi-circle from bitmap

I'm trying to clip a semi-circular chunk out of the bitmap so that it looks like this
The problem I'm having is correctly scaling the arc (so that its smaller than bitmap) and positioning it on the left edge. If I try to draw the arc in the other quadrant path.arcTo(rectF, 180-30, 60), then the concavity is pointing the wrong way.
Canvas c = new Canvas(sshotBitmap);
Path path = new Path();
RectF rectF = new
RectF(0, 0, (int)((float)social.getWidth()), social.getHeight());
path.reset();
path.arcTo(rectF, -30, 60);
path.close();
c.clipPath(path, Region.Op.DIFFERENCE);
social.draw(c);
Using arcs can be somewhat cumbersome. Since you just need a semicircular clip, an easier, and possibly more intuitive, solution would be to use the Path#addCircle() method instead, and center it on the middle of the left side of the Canvas. That is, center it at (0, c.getHeight() / 2).

How to Crop only face from an image in android?

I got a requirement to display only face from an image. But, I am trying to use only android native methods to implement this.
I have gone through the following link
Crop Image with face detection in android
But, the code mentioned in the above link is not working for all images.
Please guide me if anyone has already got the same requirement.
Thanks.
A face detection algorithm is never (and will never be) accurate. Even humans sometimes see the face of jezus in a toast. How can you expect computers to detect a face 100% correctly, if even the reference implementation (the human brain) contains bugs.
You should include a fallback scenario, when there is no (or more as one) face detected. Or do some quality check on the pictures before they are used.
You can use this rounded rectangle code with bigger corner radius to achieve a circle (recipe by Romain Guy):
BitmapShader shader;
shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setShader(shader);
RectF rect = new RectF(0.0f, 0.0f, width, height);
// rect contains the bounds of the shape
// radius is the radius in pixels of the rounded corners
// paint contains the shader that will texture the shape
canvas.drawRoundRect(rect, radius, radius, paint);

Android - Apply a bitmap texture to API drawing routines

I have a bitmap that spans the whole screen that will function as texture for a Path object that I need to draw to my canvas. I then have a background image that this textured path needs to be drawn on top of.
I tried using the PorterDuff modes, but nothing seemed to work correctly. I was having a hard time figuring out exactly how the PorterDuff modes act, because none of them seem to act the way I always thought they were supposed to function.
I've figured out a way to texture the path with this test code:
Paint paint = new Paint();
//draw the texture
canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.texture),0,0,paint);
//construct the Path with an inverse even-odd fill
Path p = new Path();
p.setFillType(Path.FillType.INVERSE_EVEN_ODD);
p.addCircle(this.getHeight()/2, this.getWidth()/2, 200, Path.Direction.CCW);
//use CLEAR to remove inverted fill, thus showing only the originally filled section
paint.setXfermode(new PorterDuffXfermode(android.graphics.PorterDuff.Mode.CLEAR));
//draw path
canvas.drawPath(p, paint);
But I can't figure out how to then place that on top of a background image. Am I just using the PorterDuff modes wrong?
Maybe my questions could lead you to your solution:
The paint used in your drawPath call:
What is the paint style?
What is the paint stroke width?
What is the paint stroke/fill color?
If you are not using a stoke/fill color, but a texture instead, where is the call to the paint's setShader (using a BitmapShader)?

transform a sqaure shape drawable in to circular shape drawable withaout affecting the pixel quality

I have an application which takes picture from camera .And normally this pictures have either rectangle shapes or square shapes.But due to make these pictures circular in shape i limited the shape to only square.So now my problem is to make this square picture into a circular shape having radius of half of width or height.And the clipped part should be removed from the picture.
Its same like making a circle from the square which touches midpoint of all of the faces of square.
I don't have any experience with canvas or other in built drawing functions.
For example i have square at first now i want to make image circular such that parts pointed by arrow should get clipped from image.
Note:as i have to work with camera images .quality is crucial factor.So please suggest the possible ways that will not affect the pixel quality and other important factors.
You can do it by masking the image with your desired shape, see this post for detailed info.
example code:
Resources resources = context.getResources();
Bitmap original = BitmapFactory.decodeResource(resources,R.drawable.original);
Bitmap mask = BitmapFactory.decodeResource(resources,R.drawable.mask);
Bitmap result = Bitmap.createBitmap(mask.getWidth(), mask.getHeight(), Config.ARGB_8888);
Canvas c = new Canvas(result);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
c.drawBitmap(original, 0, 0, null);
c.drawBitmap(mask, 0, 0, paint);
paint.setXfermode(null);
imageView.setImageBitmap(result);

Trouble making parts of a bitmap transparent

I'm developing an android app where i need to capture text and save it as a transparent image. Capturing the text has been done but making a transparent png file is where i'm stuck as i'm not familiar with image pixel manipulation at all. Here's what I have so far... i first create a blank bitmap and fill it with a white background, then i set the paint's transparency to 0 (full transparency) and then draw the source bitmap into the destination bitmap using the XOR modes.. but when i run the app all i see is a blank white image. i'll be glad if someone points out what i'm doing wrong and how to fix it. Thanks in advance.
b = Bitmap.createBitmap(tw, th,Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(b);
Rect dest = new Rect(0,0,b.getWidth(),b.getHeight());
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.WHITE);
canvas.drawRect(0, 0, b.getWidth(), b.getHeight(), paint);
paint.setAlpha(0);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.XOR));
canvas.drawBitmap(bmp,null,dest,paint);
Have you looked at : How to change a bitmap's opacity?
Seems like
paint.setAlpha(0);
won't do anything as you need to set the alpha channel to something greater than 0...
Use:
Color.argb(0,0,0,0)
The first parameter is the alpha. Set it to 0 for complete transparency.

Categories

Resources