Android: Copy and paste of an image do not work! - android

I want to copy a picture from asstets folder and paste it in my package, just for test. but final image doesn't show anything. when I want to open picture with paint, it says that "This is not a valid bitmap file".
In my program, I start to read original image in this way:
private void copyImage()
{
AssetManager am = getResources().getAssets();
try{
image = BitmapFactory.decodeStream(am.open("tasnim.png"));
imWidth = image.getWidth();
imHeight = image.getHeight();
}
catch(IOException e){
e.printStackTrace();
System.out.println("Error accoured!");
}
}
next, I'll get pixels of image or extract pixels, and save pixels in array of integer (rgbstream).
private void getPixelsOfImage()
{
rgbStream = new int[imWidth * imHeight];
image.getPixels(rgbStream, 0, imWidth, 0, 0, imWidth, imHeight);
}
finally, I want to save it in my package,
private void createPicture()
{
contextPath = context.getFilesDir().getAbsolutePath();
String path = contextPath + "/" + picName;
try{
FileOutputStream fos = new FileOutputStream(path);
DataOutputStream dos = new DataOutputStream(fos);
for(int i=0; i<rgbStream.length; i++)
dos.writeByte(rgbStream[i]);
dos.flush();
dos.close();
fos.close();
}
catch(IOException e){
System.out.println("IOException : " + e);
}
System.out.println("Picture Created.");
}
Code works fine but result, nothing!!! :(
When I check DDMS it creates new file and store all pixels (because it shows the size of this file is 13300 and dimension of my original picture is 100*133). when I click "pull a file from the device" I can save it on my desktop. However, when I open it :) nothing.
What you think? is there any problem in my code?
Thanks

I don't know what your intent is - do you want to write out a raw image file?
Assuming that you want to write a JPEG or PNG or whatever, you can erase your entire code and do something a lot easier:
Bitmap image = BitmapFactory.decodeStream(am.open("tasnim.png"));
FileOutputStream fos = new FileOutputStream(path);
image.compress(Bitmap.CompressFormat.PNG, 100, fos);
With proper error checking of course.

Related

Load images with OpenCV from assets folder in Android

I'm stuck trying to load an image placed in assets folder with OpenCV 3.0 in Android. I've read a lot of answers here, but I can't figure out what I'm doing wrong.
"my image.jpg" is place directly in the assets folder created by Android Studio.
This is the code I'm using. I've checked and the library has been loaded correctly.
Mat imgOr = Imgcodecs.imread("file:///android_asset/myimage.jpg");
int height = imgOr.height();
int width = imgOr.width();
String h = Integer.toString(height);
String w = Integer.toString(width);
if (imgOr.dataAddr() == 0) {
// If dataAddr() is different from zero, the image has been loaded
// correctly
Log.d(TAG, "WRONG UPLOAD");
}
Log.d(h, "height");
Log.d(w, "width");
When I try to run my app, this is what I get:
08-21 18:13:32.084 23501-23501/com.example.android D/MyActivity: WRONG UPLOAD
08-21 18:13:32.085 23501-23501/com.example.android D/0: height
08-21 18:13:32.085 23501-23501/com.example.android D/0: width
It seems like the image has no dimensions. I guess because it has not been loaded correctly. I'va also tried to load it placing it in the drawable folder, but it doesn't work anyway and I'd prefer to use the assets one.
Anyone can please help me and tell me how to find the right path of the image?
Thanks
Problem: imread needs absolute path and your assets are inside a apk, and the underlying c++ classes cannot read from there.
Option 1: load image into Mat without using imread from drawable folder.
InputStream stream = null;
Uri uri = Uri.parse("android.resource://com.example.aaaaa.circulos/drawable/bbb_2");
try {
stream = getContentResolver().openInputStream(uri);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
bmpFactoryOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap bmp = BitmapFactory.decodeStream(stream, null, bmpFactoryOptions);
Mat ImageMat = new Mat();
Utils.bitmapToMat(bmp, ImageMat);
Option 2: copy image to cache and load from absolute path.
File file = new File(context.getCacheDir() + "/" + filename);
if (!file.exists())
try {
InputStream is = context.getAssets().open(filename);
int size = is.available();
byte[] buffer = new byte[size];
is.read(buffer);
is.close();
FileOutputStream fos = new FileOutputStream(file);
fos.write(buffer);
fos.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
if (file.exists()) {
image = cvLoadImage(file.getAbsolutePath(), type);
}

Android picture has red tint after decoding and pulling the .png file from the emulator to pc

I am transferring some data from a server ( java app ) to client ( android app ).
The data gets Base64 encoded, sent, received correct, decoded ( correct ? ) and stored to the device ( correct ? )
I am using android studio and an AVD to simulate it. I take the pictures via DDMS from the virtual device folder to my computers harddisk in order to take a look at them. Is maybe there the problem?
now in the following code sections the picture files get decoded and stored to the device.
Cant figure out where the mistake is.
Would be glad about any hint.
byte[] imageBackToByt = Base64.decode(parts[9], Base64.DEFAULT);
Bitmap bitmapImage = BitmapFactory.decodeByteArray(imageBackToByt, 0, imageBackToByt.length);
File mediaStorageDir = new File(Environment.getExternalStorageDirectory()
+ "/Android/data/"
+ ctx.getApplicationContext().getPackageName()
+ "/Files");
File imageFile = new File(mediaStorageDir.getPath() + File.separator + voReceived.name + ".png");
try {
FileOutputStream fos = new FileOutputStream(imageFile);
bitmapImage.compress(Bitmap.CompressFormat.PNG, 90, fos);
fos.close();
} catch (FileNotFoundException e) {
Log.d(ctx.getString(R.string.SLDMP), "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d(ctx.getString(R.string.SLDMP), "Error accessing file: " + e.getMessage());
}
This is how i encode it on the server in JAVA:
BufferedImage originalPicture = null;
ByteArrayOutputStream byteArrayOS = new ByteArrayOutputStream();
byte[] pictureInByte = null;
String pictureEncoded = null;
try {
// load the original picture from the filepath
originalPicture = ImageIO.read(picturFile);
// Convert the original picture from .png format to byte array (byte []) format
ImageIO.write(originalPicture, "jpg", byteArrayOS );
pictureInByte = byteArrayOS.toByteArray();
// Encode the byte array pictureInByte to String based on Base64 encoding
pictureEncoded = Base64.getEncoder().encodeToString(pictureInByte);
} catch (IOException e) {
e.printStackTrace();
// If picture failed to load / encode store string "PICTUREERROR" as an error code
pictureEncoded = "PICTUREERROR";
}
The server puts the bytes of the image file in a buffer and sends the contents of the base 64 encoded buffer to the client. Now on client side you should directly decode base 64 all bytes and write all the resulting bytes to file. In this way you have exactly the same file. All bytes are the same and file size would be equal too.
Instead you use BitmapFactory to construct a Bitmap and then compress it to PNG. That all makes no sense.
If you want to transfer a file then do not use BitmapFactory and Bitmap.
Having said that.. Mmmmm nice filter! The result is wonderfull!

How to take a screenshot of Android's Surface View?

I want to programatically take screen shot of my game, just as you'd get in Eclipse DDMS.
Screenshot taken through the solution proposed here: How to programmatically take a screenshot in Android? and in most other SO questions only have View elements visible, but not the SurfaceView.
SCREENSHOTS_LOCATIONS = Environment.getExternalStorageDirectory().toString() + "/screenshots/";
// Get root view
View view = activity.getWindow().getDecorView().getRootView();
// Create the bitmap to use to draw the screenshot
final Bitmap bitmap = Bitmap.createBitmap(screenWidth, screenHeight, Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(bitmap);
// Get current theme to know which background to use
final Theme theme = activity.getTheme();
final TypedArray ta = theme
.obtainStyledAttributes(new int[] { android.R.attr.windowBackground });
final int res = ta.getResourceId(0, 0);
final Drawable background = activity.getResources().getDrawable(res);
// Draw background
background.draw(canvas);
// Draw views
view.draw(canvas);
// Save the screenshot to the file system
FileOutputStream fos = null;
try {
final File sddir = new File(SCREENSHOTS_LOCATIONS);
if (!sddir.exists()) {
sddir.mkdirs();
}
fos = new FileOutputStream(SCREENSHOTS_LOCATIONS
+ System.currentTimeMillis() + ".jpg");
if (fos != null) {
if (!bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos)) {
Log.d("ScreenShot", "Compress/Write failed");
}
fos.flush();
fos.close();
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Any help in this regard would be highly appreciated. Thanks.
I hope this also useful for you. here little difference for the above answer is
for I used glsurfaceview to take the screen shots hen i click the button.
this image is stored in sdcard for mentioned folder :
sdcard/emulated/0/printerscreenshots/image/...images
My Program :
View view_storelayout ;
view_storelayout = findViewById(R.id.gl_surface_view);
button onclick() {
view_storelayout.setDrawingCacheEnabled(true);
view_storelayout.buildDrawingCache(true);
Bitmap bmp = Bitmap.createBitmap(view_storelayout.getDrawingCache());
view_storelayout.setDrawingCacheEnabled(false); // clear drawing cache
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bmp.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();
}
Toast.makeText(getApplicationContext(), "myPath:"
+dir_image.toString(), Toast.LENGTH_SHORT).show();
Log.v("hari", "screenshots:"+dir_image.toString());
}
Note :
But, here i am faced one problem. In this surfaceview , i drawn line and circle
at runtime. after drawn some objects, when i take screenshots , its stored only for
black image like surfaceview is stored as an image.
And also i want to store that surfaceview image as an .dxf format(autocad format).
i tried to stored image file as an .dxf file format.its saved successfully in
autocad format. but, it cant open in autocad software to edit my .dxf file.
The code from the Usman Kurd answer will not work is most cases.
Unless you're rendering H.264 video frames in software with Canvas onto a View, the drawing-cache approach won't work (see e.g. this answer).
You cannot read pixels from the Surface part of the SurfaceView. The basic problem is that a Surface is a queue of buffers with a producer-consumer interface, and your app is on the producer side. The consumer, usually the system compositor (SurfaceFlinger), is able to capture a screen shot because it's on the other end of the pipe.
Take Screenshot of SurfaceView

VuDroid pdf viewer cannot find Bitmap to render or it doesnt render

I am trying to use the VuDroid PDF viewer and I need to take the rendered bitmap and store it as a byte[]. Then I need to convert it back into a Bitmap that can be displayed on a view using something like "canvas.drawBitmap(bitmap, 0, 0, paint);".
I have spent many hours trying to access the Bitmap and I might have done it already, but even if I get the byte[] to return something it still wont render as a Bitmap on the canvas.
Could someone please help me here, I must be missing something. Thank you so much.
I believe it is supposed to accessed via...
PDFPage.java .... public Bitmap renderBitmap(int width, int height, RectF pageSliceBounds)
-or-
through Page.java -or- DocumentView.java -or- DecodeService.java
Like I said I have tried all of these and have gotten results I just cannot see where I am going wrong since I cannot render it to see if the Bitmap was called correctly.
Thank you again :)
The doc says the method returns "null if the image could not be decode." You can try:
byte[] image = services.getImageBuffer(1024, 600);
InputStream is = new ByteArrayInputStream(image);
Bitmap bmp = BitmapFactory.decodeStream(is);
I think This will help you:-
Render a byte[] as Bitmap in Android
How does Bitmap.Save(Stream, ImageFormat) format the data?
Copy image with alpha channel to clipboard with custom background color?
if you want to get each pdf page as independent bitmap you should consider that
VuDroid render the pages,
PDFView only display them.
you should use VuDroid functions.
now you can use this example and create your own codes
Example code : for make bitmap from a specific PDF page
view = (ImageView)findViewById(R.id.imageView1);
pdf_conext = new PdfContext();
PdfDocument d = pdf_conext.openDocument(Environment.getExternalStorageDirectory() + "your PDF path");
PdfPage vuPage = d.getPage(1); // choose your page number
RectF rf = new RectF();
rf.bottom = rf.right = (float)1.0;
Bitmap bitmap = vuPage.renderBitmap(60, 60, rf); //define width and height of bitmap
view.setImageBitmap(bitmap);
for writing this bitmap on SDCARD :
try {
File mediaImage = new File(Environment.getExternalStorageDirectory().toString() + "your path for save thumbnail images ");
FileOutputStream out = new FileOutputStream(mediaImage);
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
for retrieve saved image:
File file = new File(Environment.getExternalStorageDirectory().toString()+ "your path for save thumbnail images ");
String path = file.getAbsolutePath();
if (path != null){
view = Bitmap.createScaledBitmap(BitmapFactory.decodeFile(path), YOUR_X, YOUR_Y, false);
}
Try this code to check whether bitmap is properly generating or not
PdfContext pdf_conext = new PdfContext();
PdfDocument d = (PdfDocument) pdf_conext.openDocument(pdfPath);
PdfPage vuPage = (PdfPage) d.getPage(0);
RectF rf = new RectF();
Bitmap bitmap = vuPage.renderBitmap(1000,600, rf);
File dir1 = new File (root.getAbsolutePath() + "/IMAGES");
dir1.mkdirs();
String fname = "Image-"+ 2 +".jpg";
File file = new File (dir1, fname);
if (file.exists ())
file.delete ();
try {
FileOutputStream out = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}

saving picture from my app

The idea of my app is to capture image from camera then crop specified area from it.
The problem :
When i save the cropped image in my sd card for the first time to launch the app, it saved properly. but when run my app one more time and take image then crop it. when save it the first image that take and crop at first time appear in the sd card not the current one.
This is my code for save images:
public static void save(Activity activity, Bitmap bm, String name) {
OutputStream outStream = null;
File externalFilesDir = activity.getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File outFile = new File(externalFilesDir, "IDOCR" + File.separator + "Numbers");
if (!outFile.exists())
outFile.mkdirs();
File number = new File(outFile, name + ".PNG");
//if (number.exists())
// number.delete();
try {
//outStream = new FileOutputStream(new File(path));
outStream = new FileOutputStream(number);
bm.compress(Bitmap.CompressFormat.PNG, 100, outStream);
outStream.flush();
outStream.close();
bm.recycle();
System.gc();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Maybe if you are trying to overwrite the previous version of the file, you should first delete the previous one...
You can add:
if (!outFile.exists())
outFile.mkdirs();
else {
outFile.delete();
outFile.createNewFile();
}

Categories

Resources