I just complete my photo app to using "Camera" class related implement.
However I could not see my capture photo in default Android photo album app.
Here is my code segment from my callback from Camera.takePicture:
PictureCallback jpegPictureCallback = new PictureCallback() {
#Override
public void onPictureTaken(byte[] arg0, Camera arg1) {
Bitmap bmp = BitmapFactory.decodeByteArray(arg0, 0, arg0.length);
String fileName = Environment.getExternalStorageDirectory()
.toString()
+ File.separator
+ "DCIM"
+ File.separator
+ "Camera"
+ File.separator
+ "PicTest_" + System.currentTimeMillis() + ".jpg";
File file = new File(fileName);
if (!file.getParentFile().exists()) {
file.getParentFile().mkdir();
}
try {
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream(file));
bmp.compress(Bitmap.CompressFormat.JPEG, 80, bos);
bos.flush();
bos.close();
Toast.makeText(MainPage.this, "Picture work " + fileName + "!",
Toast.LENGTH_LONG).show();
} catch (Exception e) {
// TODO Auto-generated catch block
// e.printStackTrace();
Toast.makeText(MainPage.this, "Picture Failed" + e.toString(),
Toast.LENGTH_LONG).show();
}
};
};
Please provide any idea for this, thank you.
Use MediaScannerConnection to tell the MediaStore to index your photo.
Also, please use getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), rather than the hardcoded subdirectory that you are using.
Also also, rather than decoding the byte[] to a Bitmap, then re-encoding it as a byte[], you might consider just saving the byte[].
Also also also, onPictureTaken() is called on the main application thread AFAIK; please do your image manipulations and saving to disk in a background thread.
Related
I want to save bitmaps in the gallery.
Currently, I am using the following code:
public void saveBitmap(Bitmap output){
String filepath = Environment.getExternalStorageDirectory().toString() + "/Imverter/ImverterEffectedImage";
File dir = new File(filepath);
if(!dir.exists()){
dir.mkdir();
}
String fileName = "Imverter" + System.currentTimeMillis() + ".jpg";
File image = new File(dir, fileName);
try {
FileOutputStream fileOutputStream = new FileOutputStream(image);
output.compress(Bitmap.CompressFormat.JPEG, 80, fileOutputStream);
fileOutputStream.flush();
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
It saves one single bitmap efficiently, but in my app, I have to deal with multiple bitmaps, and this method results in the slow output.
I want to store every single bitmap in a different files.
Thanks in advance.
I need to compress images before sending the images to the server via Android app. The images taken via camera are very large and they need to be compressed first. When a image is taken from Camera, there are some properties associated with the image like device model, aperture, location, etc.
I'm trying to compress the image, but during compression, those properties of the images are lost. Please help if there is any missing line of code or any library to compress the images without losing those properties.
private void compressImageAndAddToArrayList(Uri imageURI) {
Bitmap bm = null;
try
{
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;
// bm = Media.getBitmap(mContext.getContentResolver(), imageLoc);
bm = BitmapFactory.decodeStream(mContext.getContentResolver().openInputStream(imageURI), null, options);
File folder = new File(Environment.getExternalStorageDirectory() + File.separator + "VDMS" + File.separator + "Camera");
folder.mkdirs();
String now = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss").format(new Date()).toString();
String fileName = caseID + "_" + now + ".jpg";
File imageFile = new File(folder + File.separator + fileName);
FileOutputStream out = new FileOutputStream(imageFile);
bm.compress(Bitmap.CompressFormat.JPEG, 64, out); // quality ranges from 0-100
bm.recycle();
addDocumentToArrayList(String.valueOf(1), Uri.fromFile(imageFile));
}
catch (Exception e)
{
e.printStackTrace();
}
}
I am using this code to write an image to SD after camera.takePicture is called:
protected String doInBackground(byte[]... jpeg) {
File directory=new File(Environment.getExternalStorageDirectory() + "/" + getString(R.string.qpw_picture_path) + "/" + getString(R.string.qpw_picture_title) + "_" + initialTime);
directory.mkdirs();
String currentTime = new SimpleDateFormat(getString(R.string.qpw_date_format)).format(new Date());
File photo = new File (directory, getString(R.string.qpw_picture_title) + "_" + currentTime + "_" + current + ".jpg");
current++;
if (photo.exists()) {
photo.delete();
}
try {
FileOutputStream fos=new FileOutputStream(photo.getPath());
fos.write(jpeg[0]);
fos.flush();
fos.close();
}
catch (java.io.IOException e) {
}
new ImageMediaScanner(getBaseContext(), photo);
return(null);
}
Which is working fine in this case, but when I am using the same code to write images from camera.setPreviewCallback, I end up with 450KB corrupted images on SD which cannot be used or even opened.
Any help or advice would be appreciated.
Edit:
It seems that data should be first converted from YUV to RGB before saving. Having tried one of the many code samples found on Google and SO, I was facing no more issues.
Does anyone know what is the best way of doing it? In terms of speed, memory allocation, CPU...
Just in case someone stumbles on the same issue this SO post summarize well what I was looking for.
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();
}
Hi StackOverflow community,
in my application I'd like to have a button which allows the user to capture the current view.
For that reason, I've written the following method (oriented towards: Android save view to jpg or png ):
private LinearLayout container;
public void createImageOfCurrentView(View v) {
if (isExternalStoragePresent()) {
container = (LinearLayout) findViewById(R.id.container);
container.setDrawingCacheEnabled(true);
Bitmap b = container.getDrawingCache();
File dir = new File(Environment.getExternalStorageDirectory().getPath()
+ "/" + getPackageName() + "/");
dir.mkdirs();
File file = new File(dir, "image.jpg");
FileOutputStream fos;
try {
fos = new FileOutputStream(file);
b.compress(CompressFormat.JPEG, 95, fos); // NullPointerException!
Toast.makeText(this, "The current view has been succesfully saved "
+ "as image.", Toast.LENGTH_SHORT).show();
} catch (FileNotFoundException e) {
Toast.makeText(this, "Unfortunatly an error occured and this "
+ "action failed.", Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(this, "Bacause of lacking access to the storage "
+ "of this device, the current view couldn't be saved as an image.",
Toast.LENGTH_LONG).show();
}
}
The problem is according to LogCat that there occured a NullPointerException when trying to create the jpeg. So probably the method container.getDrawingCache() is not working. On the phone the file is generated. However with the size of 0 bytes and no visible image. I would appreciate any suggestions what I have to do in order to make it work as I want.
Try it -
public static Bitmap convertViewToBitmap(View view) {
Bitmap result = null;
try {
result = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.RGB_565);
view.draw(new Canvas(result));
}catch(Exception e) {}
return result;
}
Try it -
view.setDrawingCacheEnabled(true);
Bitmap = bm = Bitmap.createBitmap(view.getDrawingCache());
view.setDrawingCacheEnabled(false);