COCOS 2D screen shot is black in Android - android

I am using the following code. The image is saved but it is BLACK.
Please see my code and tell me where I am doing wrong.
I am using this code in the Menu.
case R.id.id_menu_Save:
Bitmap bmp = SavePixels(0, 0, 800, 400, CCDirector.sharedDirector().gl);
File file = new File("/sdcard/test.jpg");
try
{
file.createNewFile();
FileOutputStream fos = new FileOutputStream(file);
bmp.compress(CompressFormat.JPEG, 100, fos);
Toast.makeText(getApplicationContext(), "Image Saved", 0).show();
Log.i("Menu Save Button", "Image saved as JPEG");
}
catch (Exception e)
{
e.printStackTrace();
}
break;
This is my Save Image Function.
public static Bitmap SavePixels(int x, int y, int w, int h, GL10 gl)
{
int b[]=new int[w*(y+h)];
int bt[]=new int[w*h];
IntBuffer ib=IntBuffer.wrap(b);
ib.position(0);
gl.glReadPixels(x, 0, w, y+h, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, ib);
for(int i=0, k=0; i<h; i++, k++)
{//remember, that OpenGL bitmap is incompatible with Android bitmap
//and so, some correction need.
for(int j=0; j<w; j++)
{
int pix=b[i*w+j];
int pb=(pix>>16)&0xff;
int pr=(pix<<16)&0x00ff0000;
int pix1=(pix&0xff00ff00) | pr | pb;
bt[(h-k-1)*w+j]=pix1;
}
}
Bitmap sb = Bitmap.createBitmap(bt, w, h, Bitmap.Config.ARGB_8888);
return sb;
}
Apart from above, what I want from you is to point me in the right direction. Like if I have to get the pixels of the screen, what class/entity should I be exploring?

Just change SavePixelx method to the below:
public static Bitmap SavePixels(int x, int y, int w, int h, GL10 gl)
{
int b[]=new int[w*(y+h)];
int bt[]=new int[w*h];
IntBuffer ib=IntBuffer.wrap(b);
ib.position(0);
gl.glReadPixels(x, 0, w, y+h, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, ib);
for(int i=0, k=0; i<h; i++, k++)
{
//remember, that OpenGL bitmap is incompatible with Android bitmap
//and so, some correction need.
for(int j=0; j<w; j++)
{
int pix=b[i*w+j];
int pb=(pix>>16)&0xff;
int pr=(pix<<16)&0xffff0000;
int pix1=(pix&0xff00ff00) | pr | pb;
bt[(h-k-1)*w+j]=pix1;
}
}
Bitmap sb = Bitmap.createBitmap(bt, w, h, Bitmap.Config.ARGB_8888);
return sb;
}

just try to change GL10.GL_RGB or make changes in bitmap.config . It might be work.

Related

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

How do you convert opengl texture back to bitmap in android?

I wanted to apply image-filter to my image and used android HelloEffects sample
It converts the image data from bitmap to texture.
After applying the image filter effect, I'd like to get the image back in jpeg format, but don't know how to do that.
I did this in one way like ,
I converted the texture image into bitmap using glreadpixles() method
I then saved the bitmap to the sd card
Texture to bitmap code
public static Bitmap SavePixels(int x, int y, int w, int h){
int b[]=new int[w*(y+h)];
int bt[]=new int[w*h];
IntBuffer ib = IntBuffer.wrap(b);
ib.position(0);
GLES20.glReadPixels(0, 0, w, h, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, ib);
for(int i=0, k=0; i<h; i++, k++)
{//remember, that OpenGL bitmap is incompatible with Android bitmap
//and so, some correction need.
for(int j=0; j<w; j++)
{
int pix=b[i*w+j];
int pb=(pix>>16)&0xff;
int pr=(pix<<16)&0x00ff0000;
int pix1=(pix&0xff00ff00) | pr | pb;
bt[(h-k-1)*w+j]=pix1;
}
}
Bitmap sb=Bitmap.createBitmap(bt, w, h, Bitmap.Config.ARGB_8888);
return sb;
}
Bitmap to internal storage code,
public static void saveImage(Bitmap finalBitmap) {
File myDir=new File("/sdcard/saved_images");
myDir.mkdirs();
Random generator = new Random();
int n = 10000;
n = generator.nextInt(n);
String fname = "Image-"+ n +".jpg";
File file = new File (myDir, fname);
if (file.exists ()) file.delete ();
try {
FileOutputStream out = new FileOutputStream(file);
finalBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
Check the saveFrame() method mentioned in http://bigflake.com/mediacodec/ExtractMpegFramesTest_egl14.java.txt

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.

After Conversion of GLsurfaceview (bitmap) to pdf file , some other colors in the image is missing, in android Opengles2.0

I am developing Like an autocad app like an desktop in android using OpenGL ES2.0 . I am drawn some objects in GLSurfaceview,like lines, cirles, and linear dimensioning etc. After drawn objects on GLSurfaceview. i am capture screen of the GLSurfaceview and make the PDF File Conversion. then, open the pdf file, some objects are misssing....
This is my output First-image : my Original output , Second-image : PDF File output...
My Code:
Note: In this code, when i click the button, it will take the screenshot as image and save in sdcard location. i used Boolean condition in ondraw method if condition, why because, renderer class, ondraw method is calling anytime, anyway, this code executed without boolean condition, it saved lots of images in memory card, that's why i put this boolean condition.
MainActivity Class :
protected boolean printOptionEnable = false;
saveImageButton.setOnClickListener( new OnClickListener() {
#Override
public void onClick(View v) {
Log.v("hari", "pan button clicked");
isSaveClick = true;
myRenderer.printOptionEnable = isSaveClick;
}
} );
MyRenderer Class :
int width_surface , height_surface ;
#Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
Log.i("JO", "onSurfaceChanged");
// Adjust the viewport based on geometry changes,
// such as screen rotation
GLES20.glViewport(0, 0, width, height);
float ratio = (float) width / height;
width_surface = width ;
height_surface = height ;
}
//---------------------------------------------------------------------
#Override
public void onDrawFrame(GL10 gl) {
try {
if ( printOptionEnable ) {
printOptionEnable = false ;
Log.i("hari", "printOptionEnable if condition:"+printOptionEnable);
int w = width_surface ;
int h = height_surface ;
Log.i("hari", "w:"+w+"-----h:"+h);
int b[]=new int[(int) (w*h)];
int bt[]=new int[(int) (w*h)];
IntBuffer buffer=IntBuffer.wrap(b);
buffer.position(0);
GLES20.glReadPixels(0, 0, w, h,GLES20.GL_RGBA,GLES20.GL_UNSIGNED_BYTE, buffer);
for(int i=0; i<h; i++)
{
//remember, that OpenGL bitmap is incompatible with Android bitmap
//and so, some correction need.
for(int j=0; j<w; j++)
{
int pix=b[i*w+j];
int pb=(pix>>16)&0xff;
int pr=(pix<<16)&0x00ff0000;
int pix1=(pix&0xff00ff00) | pr | pb;
bt[(h-i-1)*w+j]=pix1;
}
}
Bitmap inBitmap = null ;
if ( inBitmap == null || !inBitmap.isMutable() ||
inBitmap.getWidth() != w || inBitmap.getHeight() != h) {
inBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
}
//Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
inBitmap.copyPixelsFromBuffer(buffer);
//return inBitmap ;
// return Bitmap.createBitmap(bt, w, h, Bitmap.Config.ARGB_8888);
inBitmap = Bitmap.createBitmap(bt, w, h, Bitmap.Config.ARGB_8888);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
inBitmap.compress(CompressFormat.JPEG, 90, bos);
byte[] bitmapdata = bos.toByteArray();
ByteArrayInputStream fis = new ByteArrayInputStream(bitmapdata);
final Calendar c=Calendar.getInstance();
long mytimestamp=c.getTimeInMillis();
String timeStamp=String.valueOf(mytimestamp);
String myfile="hari"+timeStamp+".jpeg";
dir_image=new File(Environment.getExternalStorageDirectory()+File.separator+
"printerscreenshots"+File.separator+"image");
dir_image.mkdirs();
try {
File tmpFile = new File(dir_image,myfile);
FileOutputStream fos = new FileOutputStream(tmpFile);
byte[] buf = new byte[1024];
int len;
while ((len = fis.read(buf)) > 0) {
fos.write(buf, 0, len);
}
fis.close();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Log.v("hari", "screenshots:"+dir_image.toString());
}
} catch(Exception e) {
e.printStackTrace() ;
}
}
Please Any one help me..
Thanks Advance

opengles2 screen shot

I am trying to capture a screenshot of what is rendered onto the screen. I have tried using glreadpixels but the results were all zeros. I'm happy to know if there are any other methods of capturing the glsurfaceview as well. Thanks a lot!
The following is a code snippet I've obtained from another thread:
public Bitmap savePixels(int x, int y, int w, int h){
int b[]=new int[w*(y+h)];
int bt[]=new int[w*h];
IntBuffer ib=IntBuffer.wrap(b);
ib.position(0);
GLES20.glReadPixels(x, 0, w, y+h, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, ib);
for(int i=0, k=0; i<h; i++, k++)
{//remember, that OpenGL bitmap is incompatible with Android bitmap
//and so, some correction need.
for(int j=0; j<w; j++)
{
int pix=b[i*w+j];
int pb=(pix>>16)&0xff;
int pr=(pix<<16)&0x00ff0000;
int pix1=(pix&0xff00ff00) | pr | pb;
bt[(h-k-1)*w+j]=pix1;
int test = pix;
if (pix > 0)
System.out.println(test%256 + " " + (test/256)%256 + " " + (test/256/256)%256 + " " + test/256/256/256);
}
}
return Bitmap.createBitmap(bt, w, h, Bitmap.Config.ARGB_8888);
}

Categories

Resources