how to get bitmap from GLSurfaceView in android - android

I have made a photo Effect demo. In that I am applying different effects on android.opengl.GLSurfaceView. All done successfully, but when I am going to take bitmap from that View, I got a black transparent bitmap with bitmap. I want to take only bitmap of image (not that black background).
Can anyone please help me to solve it.
code
<android.opengl.GLSurfaceView
android:id="#+id/iv_effect_img"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
java code
public Bitmap takeScreenshot(GL10 mGL) {
final int mWidth = mEffectView.getWidth();
final int mHeight = mEffectView.getHeight();
IntBuffer ib = IntBuffer.allocate(mWidth * mHeight);
IntBuffer ibt = IntBuffer.allocate(mWidth * mHeight);
mGL.glReadPixels(0, 0, mWidth, mHeight, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, ib);
// Convert upside down mirror-reversed image to right-side up normal
// image.
for (int i = 0; i < mHeight; i++) {
for (int j = 0; j < mWidth; j++) {
ibt.put((mHeight - i - 1) * mWidth + j, ib.get(i * mWidth + j));
}
}
Bitmap mBitmap = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888);
mBitmap.copyPixelsFromBuffer(ibt);
Global.img = mBitmap;
return mBitmap;
}

Related

Save segmentation result of Selfie segmentation with ML Kit on Android as A Bitmap with transparent background

Save segmentation result of Selfie segmentation with ML Kit on Android as A Bitmap with transparent background
I am following this tutorial and code for Selfie segmentation
Here
I have referred this code from the tutorial
ByteBuffer mask = segmentationMask.getBuffer();
int maskWidth = segmentationMask.getWidth();
int maskHeight = segmentationMask.getHeight();
for (int y = 0; y < maskHeight; y++) {
for (int x = 0; x < maskWidth; x++) {
// Gets the confidence of the (x,y) pixel in the mask being in the foreground.
float foregroundConfidence = mask.getFloat();
}
}
Which generates a Mask
Then I have Referred the Sample app Which generates a purple background Mask
Here
using this code
#ColorInt
private int[] maskColorsFromByteBuffer(ByteBuffer byteBuffer) {
#ColorInt int[] colors = new int[maskWidth * maskHeight];
for (int i = 0; i < maskWidth * maskHeight; i++) {
float backgroundLikelihood = 1 - byteBuffer.getFloat();
if (backgroundLikelihood > 0.9) {
colors[i] = Color.argb(128, 255, 0, 255);
} else if (backgroundLikelihood > 0.2) {
// Linear interpolation to make sure when backgroundLikelihood is 0.2, the alpha is 0 and
// when backgroundLikelihood is 0.9, the alpha is 128.
// +0.5 to round the float value to the nearest int.
int alpha = (int) (182.9 * backgroundLikelihood - 36.6 + 0.5);
colors[i] = Color.argb(alpha, 255, 0, 255);
}
}
return colors;
}
Now I want to generate an Image with the original images detected mask and Overlay it on a Transparent Image and save that bitmap for this I am using this code
public Bitmap generateMaskBgImage(Bitmap image, Bitmap bg) {
//Bg is Transparent Png Image.
Bitmap bgBitmap = Bitmap.createBitmap(image.getWidth(), image.getHeight(), image.getConfig());
for (int y = 0; y < maskHeight; y++) {
for (int x = 0; x < maskWidth; x++) {
int bgConfidence = (int) ((1.0 - maskBuffer.getFloat()) * 255);
int bgPixel = bg.getPixel(x, y);
bgPixel = ColorUtils.setAlphaComponent(bgPixel, bgConfidence);
bgBitmap.setPixel(x, y, bgPixel);
}
}
maskBuffer.rewind();
return bitmapUtils.mergeBitmaps(image, bgBitmap);
}
However it generates an Image with the desired mask but with a Black back ground, How can we save that image with Transparent background.
You can try this (color1 is the color you set in the mask):
private Bitmap performBW(Bitmap originBitmap,Bitmap maskBitmap) {
Bitmap bmOut = Bitmap.createBitmap(originBitmap.getWidth(), originBitmap.getHeight(),
originBitmap.getConfig());
int w = originBitmap.getWidth();
int h = originBitmap.getHeight();
int[] colors = new int[w * h];
int[] colorsMask=new int[maskBitmap.getWidth() * maskBitmap.getHeight()];
originBitmap.getPixels(colors, 0, w, 0, 0, w, h);
maskBitmap.getPixels(colorsMask, 0, w, 0, 0, w, h);
int pos;
for (int i = 0; i < h; i++) {
for (int j = 0; j < w; j++) {
pos = i * w + j;
if (colorsMask[pos] == color1) colors[pos]=Color.TRANSPARENT;
}
}
bmOut.setPixels(colors, 0, w, 0, 0, w, h);
return bmOut;
}

Modifying bitmap is very slow...Is there any other way for this?

I am here trying to convert my current bitmap in black and white bitmap by writing following method.But it takes very long time to convert because of its for loop of every pixels.Am i wrong here any where? or is there any other way to do this?..Help will be appreciated.Thank you.
My Code:
public Bitmap convert(Bitmap src) {
final double GS_RED = 0.299;
final double GS_GREEN = 0.587;
final double GS_BLUE = 0.114;
int A, R, G, B;
final int width = src.getWidth();
final int height = src.getHeight();
int pixels[] = new int[width * height];
int k = 0;
Bitmap bitmap = Bitmap.createBitmap(width, height, src.getConfig());
src.getPixels(pixels, 0, width, 0, 0, width, height);
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int pixel = pixels[x + y * width];
A = Color.alpha(pixel);
R = Color.red(pixel);
G = Color.green(pixel);
B = Color.blue(pixel);
R = G = B = (int) (GS_RED * R + GS_GREEN * G + GS_BLUE * B);
pixels[x + y * width] = Color.argb(
A, R, G, B);
}
}
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
return bitmap;
}
You can easily convert rgb image to grayscale using this method without looping through all pixels
public Bitmap toGrayscale(Bitmap bmp)
{
int originalwidth, originalheight;
originalheight = bmp.getHeight();
originalwidth = bmp.getWidth();
Bitmap bmpGrayscale = Bitmap.createBitmap(originalwidth, originalheight, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bmpGrayscale);
Paint paint = new Paint();
ColorMatrix cm = new ColorMatrix();
cm.setSaturation(0);
ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
paint.setColorFilter(f);
c.drawBitmap(bmp, 0, 0, paint);
return bmpGrayscale;
}

How to get the bitmap image from a GLSurfaceView

I am doing the following to get the bitmap image that has been set to a GLSurfaceView object:
glView.setDrawingCacheEnabled(true);
glView.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
glView.layout(0, 0, glView.getMeasuredWidth(), glView.getMeasuredHeight());
glView.buildDrawingCache(true);
Bitmap tmpbm = Bitmap.createBitmap(glView.getDrawingCache());
glView.setDrawingCacheEnabled(false);
But glView.getDrawingCache() is returning me null in the above case, and hence it is crashing in the line Bitmap tmpbm = Bitmap.createBitmap(glView.getDrawingCache());
Why am I getting null from there, and how do I tackle this issue? Also, is there a different / better way to achieve my goal? Any help would be highly appreciated.
Try this method :
private Bitmap createBitmapFromGLSurface(int x, int y, int w, int h, GL10 gl)
throws OutOfMemoryError {
int bitmapBuffer[] = new int[w * h];
int bitmapSource[] = new int[w * h];
IntBuffer intBuffer = IntBuffer.wrap(bitmapBuffer);
intBuffer.position(0);
try {
gl.glReadPixels(x, y, w, h, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, intBuffer);
int offset1, offset2;
for (int i = 0; i < h; i++) {
offset1 = i * w;
offset2 = (h - i - 1) * w;
for (int j = 0; j < w; j++) {
int texturePixel = bitmapBuffer[offset1 + j];
int blue = (texturePixel >> 16) & 0xff;
int red = (texturePixel << 16) & 0x00ff0000;
int pixel = (texturePixel & 0xff00ff00) | red | blue;
bitmapSource[offset2 + j] = pixel;
}
}
} catch (GLException e) {
return null;
}
return Bitmap.createBitmap(bitmapSource, w, h, Bitmap.Config.ARGB_8888);
}
more here

Change inSampleSize of a Bitmap

I am creating a bitmap from glsurfaceview and adding it to a arraylist but when I created a bitmap from glsurfaceview it gives outofmemory error
CODE:
Bitmap bitmap = createBitmapFromGLSurface(0, 0, mEffectView.getWidth(),
mEffectView.getHeight(), gl);
al_bitmaps.add(bitmap);
Method:
private Bitmap createBitmapFromGLSurface(int x, int y, int w, int h, GL10 gl)
throws OutOfMemoryError {
int bitmapBuffer[] = new int[w * h];
int bitmapSource[] = new int[w * h];
IntBuffer intBuffer = IntBuffer.wrap(bitmapBuffer);
intBuffer.position(0);
try {
gl.glReadPixels(x, y, w, h, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE,
intBuffer);
int offset1, offset2;
for (int i = 0; i < h; i++) {
offset1 = i * w;
offset2 = (h - i - 1) * w;
for (int j = 0; j < w; j++) {
int texturePixel = bitmapBuffer[offset1 + j];
int blue = (texturePixel >> 16) & 0xff;
int red = (texturePixel << 16) & 0x00ff0000;
int pixel = (texturePixel & 0xff00ff00) | red | blue;
bitmapSource[offset2 + j] = pixel;
}
}
} catch (GLException e) {
return null;
}
return Bitmap.createBitmap(bitmapSource, w, h, Bitmap.Config.ARGB_8888);
}
For larger resolution device (ex. Samsung Galaxy S4), my app crashes.
I would like to know how to set inSampleSize of that bitmap.
First of all i will recommended to you use
android:largeHeap="true"
in your manifest file.
Secondary if that not helped to you look that https://stackoverflow.com/a/17839597/2956344
Also i recommend to you know about maximum texture size of your GLSufaceView to check limit of your bitmap resolution programmatically.
Get Maximum OpenGL ES 2.0 Texture Size Limit in Android
P.S. I think you find information about use GL10.

android noise effect on bitmap

I am writing some function to add noise effect on bitmap. I found similar question: Add noise effect to a drawing
Bitmap outputBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
BitmapShader shader = new BitmapShader (bitmap, TileMode.REPEAT, TileMode.REPEAT);
Paint paint = new Paint();
paint.setShader(shader);
Canvas c = new Canvas(outputBitmap);
c.drawBitmap(bitmap, 0, 0, paint);
How should i add color filter to get such a result? Could you provide somple code?
i suggested that use this code.
public static final int COLOR_MIN = 0x00;
public static final int COLOR_MAX = 0xFF;
public static Bitmap applyFleaEffect(Bitmap source) {
// get image size
int width = source.getWidth();
int height = source.getHeight();
int[] pixels = new int[width * height];
// get pixel array from source
source.getPixels(pixels, 0, width, 0, 0, width, height);
// a random object
Random random = new Random();
int index = 0;
// iteration through pixels
for(int y = 0; y < height; ++y) {
for(int x = 0; x < width; ++x) {
// get current index in 2D-matrix
index = y * width + x;
// get random color
int randColor = Color.rgb(random.nextInt(COLOR_MAX),
random.nextInt(COLOR_MAX), random.nextInt(COLOR_MAX));
// OR
pixels[index] |= randColor;
}
}
// output bitmap
Bitmap bmOut = Bitmap.createBitmap(width, height, source.getConfig());
bmOut.setPixels(pixels, 0, width, 0, 0, width, height);
return bmOut;
}
welcome.

Categories

Resources