create a mask from bitmap - android

I have an image as bitmap e.g
I want to create mask programmatically from that bitmap like this
I searched online but did not find any solution.

2003 Java Q and A about Masking Images
The question posed on this website seems similar to yours and the answers should help you out. Their code was written in Java back in 2003, but I believe you are asking about something you plan to program in Android Studio from your tags in I am guessing Java. Your question is kind of vague, but maybe this website will be a good starting point. There are longer solutions, with complete code written out, but I'll post one of the solutions listed.
One of the Solutions posted on that forum is this:
//get the image pixel
int imgPixel = image.getRGB(x,y);
//get the mask pixel
int maskPixel = mask.getRGB(x,y);
//now, get rid of everything but the blue channel
//and shift the blue channel into the alpha channels sample space.
maskPixel = (maskPixel &0xFF)<<24
//now, merge img and mask pixels and copy them back to the image
image.setRGB(x,y,imgPixel|maskPixel);

I found a solution to my problem i solved my problem by tinting my bitmap using PorterDuffColorFilter in a following way.
public Bitmap tintBitmap(Bitmap bitmap, int color) {
Paint paint = new Paint();
paint.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN));
Bitmap bitmapResult = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmapResult);
canvas.drawBitmap(bitmap, 0, 0, paint);
return bitmapResult;
}

Related

How to restore a Bitmap after erasing a part of it, while preserving its alpha?

I am working on an android application which has 2 features:-
is to remove(erase) a part of the image for a given path, just like the eraser
in photoshop.
is to restore the image for a given path.
I've implemented the erasing part
mEraserPaint = new Paint(1);
mEraserPaint.setDither(true);
mEraserPaint.setAntiAlias(true);
mEraserPaint.setFilterBitmap(true);
mEraserPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
mEraserPaint.setStyle(Paint.Style.STROKE);
mEraserPaint.setStrokeJoin(Paint.Join.ROUND);
mEraserPaint.setStrokeCap(Paint.Cap.ROUND);
mEraserPaint.setStrokeWidth(this.strokeWidth);
mEditingCanvas.drawPath(mPath, mEraserPaint);
And, the repair feature like,
mRepairPaint = new Paint(1);
mRepairPaint.setDither(true);
mRepairPaint.setAntiAlias(true);
mRepairPaint.setFilterBitmap(true);
mRepairPaint.setStyle(Paint.Style.STROKE);
mRepairPaint.setStrokeJoin(Paint.Join.ROUND);
mRepairPaint.setStrokeCap(Paint.Cap.ROUND);
mRepairPaint.setStrokeWidth(this.strokeWidth);
mRepairPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
Bitmap overlay = Bitmap.createBitmap(mOriginalBitmap.getWidth(),
mOriginalBitmap.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(overlay);
canvas.drawPath(mPath, mRepairPaint);
mRepairPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(mOriginalBitmap, 0, 0, mRepairPaint);
mRepairPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER));
mEditingCanvas.drawBitmap(overlay, 0, 0, mRepairPaint);
The problem is that, in the repair feature alpha of the image is not preserved and the image is drawn with full opacity. I need to preserve the alpha of image.
So, I need to know how to repair an image after erasing a part of it, while preserving its alpha.

Android - Bitmap Interpolation?

I'm trying to render some pixel art on a Bitmap on a canvas.
What I want it to look like:
http://puu.sh/9e8Ig/0cc6663b6c.png
What it is rendering like:
http://puu.sh/9e8JR/9ec821d9f8.png
This is the code for when they're defined:
Bitmap gameovertitle;
gameovertitle = BitmapFactory.decodeResource(getResources(), R.raw.pnggameovertext);
gameovertitle = Bitmap.createScaledBitmap(gameovertitle, CanvasWidth, (int) (CanvasWidth / 2.48), **false**);
Code for where it's drawn:
c.drawBitmap(menuplaybuttons, 0, 0, null);
Does anyone know how to fix this? :/
I believe the problem has to do with the interpolation.
I've searched tons of different posts but cant seem to find any helpful information.
Any help would be greatly appreciated.
Thanks,
Jason
You can create a Canvas and a Bitmap as its output
Then draw the bitmaps one by one on the resultant Bitmap

How to create canvas with large Bitmap, draw on it, and then scale to screen size to conserve memory?

Simply put, I have a Bitmap resource that is 1800 x 1800 pix due to the detail I need. I create a canvas from the Bitmap and then draw on it. After drawing is complete, It's attached to an ImageView. It works fine on devices with large Heaps but on small devices, it crashes. The Bitmap needs to be the same size for all devices when added to the canvas because the coordinates that I draw to are precise locations on the Bitmap.
Here is my code
initialBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.VeryLargeBitmap);
mutableBitmap = initialBitmap.copy(Bitmap.Config.RGB_565, true);
canvas = new Canvas(mutableBitmap);
....draw stuff here
canvas.drawLine(x, y, x2, y2, paint);
ImageView.setImageBitmap(mutableBitmap);
ImageView..setAdjustViewBounds(true);
I'm sure there is a better way. I have looked into OpenGL but have not tried it yet. It looks to complex for what I'm trying to accomplish.
BitmapFactory.Options o = new BitmapFactory.Options();
o.inMutable = true;
initialBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.VeryLargeBitmap, o);
Doing this should remove the need to copy the bitmap to an immutable one. When you're done with it (saved to file or ready for a new one) do this:
initialBitmap.recycle();
initialBitmap = null;
To remove any reference to it (NOTE: recycle may not be necessary but I like it "to make sure").
EDIT:
Special note is that creating a Bitmap is CPU intensive so it'd be best to decode it in a thread and start drawing when it's ready. You should never create a Bitmap in an onDraw or draw method.

Drawing bitmaps with alpha channel: please advise... (some solutions and speed issues)

I have a rather big number of small bitmaps (100+, size about 40x40) each one have some opaque and some transparent parts and i need to paint them respecting these areas.
Bitmaps are in ARGB format, 888(rgb) plus a 256bit alpha channel, standard like in PNG format.
The only (working) way i found to draw them is the following approach:
create a bitmap (ARGB_8888)
fill the bitmap with the raw data
extract the alpha layer from the bitmap
create a BitmapShader (RGB_565) based on the original bitmap
Create a paint for the bitmap which uses the created shader
Then paint the alpha mask using the paint with the special BitmapShader.
The initialization code is run only once, of course:
void initializeTile( int t ){
// Allocate the bitmap:
Bitmap original_data = Bitmap.createBitmap( tile_w, tile_h, Bitmap.Config.ARGB_8888);
// Fill with raw data (this is actually native C++ code):
populateBitmap( original_data );
// Get the alpha mask:
tile_mask[ t ] = original_data.extractAlpha();
// Create the bitmap shader:
tile_data = original_data.copy( Bitmap.Config.RGB_565, false);
// Create the shader:
BitmapShader shader = new BitmapShader(tile_data, CLAMP, CLAMP);
// Create the paint:
tile_paint[ t ] = new Paint();
tile_paint[ t ].setDither(true);
tile_paint[ t ].setAntiAlias(true);
tile_paint[ t ].setFilterBitmap(true);
tile_paint[ t ].setShader( shader );
}
And the paint code is the most simple possible, and it's in the main draw loop:
void paintTile(t){
canvas.drawBitmap( tile_mask[ t ], tile_x[ t], tile_y[ t], tile_paint[ t] );
}
Now, on phones like the Ideos (Android 2.2) it run smooth and fine, but on other phones like the top-end Samsung Galaxy SII (Android 2.3) it's crappy and slow. This does not make much sense to me...
So, what do you think of this approach? Are there better, faster, ways to achieve the same result?
And, why do you think it's so slow on modern, fast hardware? Is there any ways to improve it?
Ok, after some work i found out a better solution. I cannot answer my own questions, so please do if you know more than me.
But, in case more people needs this, i am posting my new solution, which is much faster albeit a bit more complicated. The key idea is to use the shader approach ONLY during initialization and not for painting.
To do this, i create a new bitmap which will contain the "clipped" bitmap (with all the transparent areas cleared) using the shader approach, then paint that clipped bitmap without any shader in the draw code.
void initializeTile( int t ){
// Allocate the bitmap:
Bitmap original_data = Bitmap.createBitmap( tile_w, tile_h, Bitmap.Config.ARGB_8888);
// Fill with raw data (this is actually native C++ code):
populateBitmap( original_data );
// Now make a new bitmap to be clipped:
Bitmap clipped_data = Bitmap.createBitmap( tile_w, tile_h, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(clipped_data);
Paint clip_paint = new Paint();
clip_paint.setDither(true);
clip_paint.setAntiAlias(true);
clip_paint.setFilterBitmap(true);
clip_paint.setShader( new BitmapShader(original_data, CLAMP, CLAMP));
// Paint the clipped bitmap:
canvas.drawBitmap( tile_mask[ t ], 0, 0, clip_paint );
//Use the clipped bitmap as original bitmap:
tile_data[ t ] = clipped_data;
}
And also drawing code:
void paintTile(t){
canvas.drawBitmap( tile_data[ t ], tile_x[ t], tile_y[ t], null );
}
Overall, this is much faster.
Still it's unclear to me WHY Android would not paint my alpha-channelled bitmaps properly without all this mess!

Android ZXing image processing

I have to scan a Data Matrix written on something like this.
The code is white/light gray but the background reflects different colors, depending on the position of the camera(angle), light.
Where would be the right place to edit the image captured in Android Zxing?
Is there any possible adjustment to make the image black on white before processing?
Any idea would be great.
Bitmap bm = Bitmap.createBitmap(500, 500, Bitmap.Config.RGB_565);
Canvas c = new Canvas(bm);
Paint paint = new Paint();
ColorMatrix cm = new ColorMatrix();
cm.setSaturation(0);
ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
paint.setColorFilter(f);
int xo = (w-500)/2;
int yo = (h-500)/2;
c.drawBitmap(bmp, -xo, -yo, paint);
bmp.recycle();
Also have a look at this class:
http://zxing.org/w/docs/javadoc/com/google/zxing/common/HybridBinarizer.html
Maybe you are using by default the GlobalHistogramBinarizer, which is faster but doesn't work so good with gradients.
It seems that you need some image processing before recognition. Previous answer suggest histogram bianrizer, which is sensitive to background intensity changes. Sauvola filter is known to have good tolerance to background changes ( and gradients), but has higher processing time.
( Implemented in our OCR Project: http://sourceforge.net/projects/javaocr/ , and you can see it in action
in this application: https://market.android.com/details?id=de.pribluda.android.ocrcall&feature=search_result )

Categories

Resources