Saved Bitmap to PNG File randomly goes black - android

I'm processing about 4 images / seconds from camera preview, save it to png File and send it to a server.
I couldn't yet identify why, but 1 time out of 2 the current session will store the .png as full black pictures. the File size is also very small (3kb vs the usual 700kb).
Here's how I store the Bitmap as a PNG file :
public static File SaveImagePNG(Bitmap subimg, String path, String filename) {
FileOutputStream out = null;
File sd = new File(path);
boolean success = true;
if (!sd.exists()) {
success = sd.mkdir();
}
if (success) {
File dest = new File(sd, filename);
try {
out = new FileOutputStream(dest);
if (subimg != null) {
// PNG is a lossless format, the compression factor (100) is ignored
subimg.compress(Bitmap.CompressFormat.PNG, 100, out); // bmp is your Bitmap instance
}
} catch (Exception e) {
e.printStackTrace();
Log.d(TAG, e.getMessage());
} finally {
try {
if (out != null) {
out.close();
Log.d(TAG, "OK!!");
}
} catch (IOException e) {
Log.d(TAG, e.getMessage() + "Error");
e.printStackTrace();
}
}
return dest;
}
return null;
}
and here's how I call it :
val pathFilePNG = Environment.getExternalStorageDirectory().toString() + "/images"
requestParams[0]?.bitmapRGB?.setHasAlpha(false)
val imageFaceRGBFile = BitmapUtils.SaveImagePNG(requestParams[0]?.bitmapRGB, pathFilePNG, "faceRGB.png")

Related

what is different bitmap compress option in Android webview

when I upload my captured webveiw(bitmap image), I use this :
public static void saveBitmaptoPng(Bitmap bitmap, String folder, String name) {
String ex_storage = Environment.getExternalStorageDirectory().getAbsolutePath();
// Get Absolute Path in External Sdcard
String foler_name = "/" + folder + "/";
String file_name = name + ".png";
String string_path = ex_storage + foler_name;
File file_path;
try {
file_path = new File(string_path);
if (!file_path.isDirectory()) {
file_path.mkdirs();
}
FileOutputStream out = new FileOutputStream(string_path + file_name);
**bitmap.compress(Bitmap.CompressFormat.PNG, 90, out);**
out.close();
} catch (FileNotFoundException exception) {
Log.e("FileNotFoundException", exception.getMessage());
} catch (IOException exception) {
Log.e("IOException", exception.getMessage());
}
}
It is working well. but when I change 90 to 100 of Bitmap.CompressFormat,
I got an error whe getresponseCode
int serverResponseCode = connection.getResponseCode();
if (serverResponseCode == HttpURLConnection.HTTP_OK) {
is = new BufferedInputStream(connection.getInputStream());
} else {
is = new BufferedInputStream(connection.getErrorStream());
return null;
}
when changing from 90 to 100, process flow errorStream.... but I don't know any reasons.... even 95 is also not working well..

How to properly extract files (out of memory)?

At start up of my app I want to extract my images (if they does not exists) from drawable folder to internal app folder to use later with FileProvider. Images have dimensions 2000*2000 and average size 380kb, format png.
Those images are not to be displayed (smaller ones are used to display). They are only for file sharing and I have to keep their original size.
I get out of memory at calling
Bitmap bm = BitmapFactory.decodeResource(getResources(), imageResID);
Code
private void extractImages() {
TypedArray imgs = getResources().obtainTypedArray(R.array.smile_list_share);
File imagePath = new File(getFilesDir(), "images");
File checkImage;
for (int i = 0; i < imgs.length(); i++) {
int imageResID = imgs.getResourceId(i, 0);
if (imageResID > 0) {
String name = getResources().getResourceEntryName(imageResID);
checkImage = new File(imagePath, name + ".png");
if (!checkImage.exists()) {
Bitmap bm = BitmapFactory.decodeResource(getResources(), imageResID);
boolean b = saveBitmapToFile(imagePath, name + ".png", bm, Bitmap.CompressFormat.PNG, 100);
Log.e("mcheck","saved "+b+", file "+name);
Log.e("mcheck", "file does not exists " + name);
} else {
Log.e("mcheck", "file exists " + name);
}
} else {
Log.e("mcheck", "ERROR " + i);
}
}
imgs.recycle();
}
public boolean saveBitmapToFile(File dir, String fileName, Bitmap bm,
Bitmap.CompressFormat format, int quality) {
File imageFile = new File(dir, fileName);
FileOutputStream fos = null;
try {
fos = new FileOutputStream(imageFile);
bm.compress(format, quality, fos);
bm.recycle();
fos.close();
return true;
} catch (IOException e) {
Log.e("app", e.getMessage());
if (fos != null) {
try {
fos.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
return false;
}
You have to call recycle on your bitmap object everytime you are done with it.
Here is a good guide on how to manipulate bitmaps efficiently
https://developer.android.com/training/displaying-bitmaps/load-bitmap.html
I found that I dont need to create bitmap object at all. It is possible to obtaine intput stream from getResourses directly.
public boolean saveBitmapToFile(File dir, String fileName, int imageResourse) {
File imageFile = new File(dir, fileName);
FileOutputStream fos = null;
InputStream inputStream = null;
try {
fos = new FileOutputStream(imageFile);
inputStream = getResources().openRawResource(imageResourse);
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
int len = 0;
while ((len = inputStream.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
inputStream.close();
fos.close();
return true;
} catch (IOException e) {
Log.e("app", e.getMessage());
if (fos != null) {
try {
fos.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
return false;
}

How to retain image quality after uploading it to a server?

The code works fine, but the image that is produced looses a good amount of quality. Compression format used is PNG. And also how can I make the image to be saved as .png and not as a .file.
public static void writeBitmapToDisk(String filename, Bitmap paramBitmap,
Context paramContext, Bitmap.CompressFormat paramCompressFormat) {
Log.e("CL", "paramBitmap.getByteCount()" + paramBitmap.getByteCount());
String str = constructFileName(filename);
if (paramBitmap != null) {
try {
FileOutputStream localFileOutputStream = paramContext
.openFileOutput(str, 0);
Log.e("CL", "localFileOutputStream" + localFileOutputStream);
paramBitmap.compress(paramCompressFormat, 100,
localFileOutputStream);
localFileOutputStream.close();
return;
} catch (FileNotFoundException localFileNotFoundException) {
localFileNotFoundException.printStackTrace();
return;
} catch (IOException localIOException) {
localIOException.printStackTrace();
}
}
}

How to load a image from assets?

i need to load a image from assets to avoid a froyo 2.2.2 bug resizing POT images in some particular cases. The way to avoid it is loading the image files from assets dir.
I'm trying to do with this:
String imagePath = "radiocd5.png";
AssetManager mngr = context.getAssets();
// Create an input stream to read from the asset folder
InputStream is = null;
try {
is = mngr.open(imagePath);
} catch (IOException e1) { e1.printStackTrace();}
//Get the texture from the Android resource directory
//InputStream is = context.getResources().openRawResource(R.drawable.radiocd5);
Bitmap bitmap = null;
try {
//BitmapFactory is an Android graphics utility for images
bitmap = BitmapFactory.decodeStream(is);
} finally {
//Always clear and close
try {
is.close();
is = null;
} catch (IOException e) {}
}
But i am getting NullPointerException on the line is.close();
i capture a FileNotFoundException: radiocd5.png, but that file is on my assets directory :S
What am i doing bad? The file is called radiocd5.png and it is on the assets directory
You can follow my tutorials on displaying data from Assets: https://xjaphx.wordpress.com/2011/10/02/store-and-use-files-in-assets/
The sample with loading image and text to display.
I now added the relevant part of the provided link
(in case of earthquake or something) ;-) Taifun
// load image
try {
// get input stream
InputStream ims = getAssets().open("avatar.jpg");
// load image as Drawable
Drawable d = Drawable.createFromStream(ims, null);
// set image to ImageView
mImage.setImageDrawable(d);
}
catch(IOException ex) {
return;
}
Instead of using the assets dir, put the file into /res/raw, and you can then access it using the following URI: android.resource://com.your.packagename/" + R.raw.radiocd5
try {
InputStream istr = this.context.getAssets().open(P.strImage);
//set drawable from stream
this.imgProduct.setImageDrawable(Drawable.createFromStream(istr, null));
} catch (IOException e) {
e.printStackTrace();
}
protected String openImageInAssets(String imageName) {
String encodedImageBase64 = "";
AssetManager assetManager = getAssets();
InputStream fileStream = null;
try {
fileStream = assetManager.open(imageName);
if (fileStream != null) {
// BitmapFactory.Options bfo = new BitmapFactory.Options();
// bfo.inPreferredConfig = Bitmap.Config.ARGB_8888;
// Bitmap bitmap = BitmapFactory.decodeStream(fileStream, null, bfo);
Bitmap bitmap = BitmapFactory.decodeStream(fileStream);
// Convert bitmap to Base64 encoded image for web
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
// to get image extension file name split the received
int fileExtensionPosition = imageName.lastIndexOf('.');
String fileExtension = imageName.substring(fileExtensionPosition+1);
// Log.d(IConstants.TAG,"fileExtension: " + fileExtension);
if (fileExtension.equalsIgnoreCase("png")) {
bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
// Log.d(IConstants.TAG,"fileExtension is PNG");
} else if (fileExtension.equalsIgnoreCase("jpg") || fileExtension.equalsIgnoreCase("jpeg")) {
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream);
// Log.d(TAG,"fileExtension is JPG");
}
byte[] byteArray = byteArrayOutputStream.toByteArray();
String imgageBase64 = Base64.encodeToString(byteArray, Base64.DEFAULT);
encodedImageBase64 = "data:image/png;base64," + imgageBase64;
}
} catch (IOException e) {
e.printStackTrace();
return encodedImageBase64="";
} finally {
//Always clear and close
try {
if (fileStream != null) {
fileStream.close();
fileStream = null;
}
} catch (IOException e) {
e.printStackTrace();
}
}
// Log.d(TAG,"encodedImageBase64: " + encodedImageBase64);
return encodedImageBase64;
}
Here is an alternative way
setImageBitmap(BitmapFactory.decodeStream(assets.open("photo.jpg")))
Another version, inside a fragment:
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
root = inflater.inflate(R.layout.createrestaurant_layout, container, false);
Resources res = getResources();
img = (ImageView) root.findViewById(R.id.img);
AssetManager amanager = res.getAssets();
try {
InputStream imageStream = amanager.open("restaurant.jpg");
Drawable drawable = new BitmapDrawable(res, imageStream);
img.setImageDrawable(drawable);
} catch (Exception e) {
e.printStackTrace();
}
}
This process seems much simpler in iOS/UIKit or iOS/SwiftUI.

Android, can't read images I saved to data folder

My app uses the following piece of code to write out images I have resized into the app's data folder:
private void writeImage(Bitmap bmp, String filename)
{
try
{
FileOutputStream stream = openFileOutput(filename, MODE_WORLD_WRITEABLE);
bmp.compress(CompressFormat.PNG, 100, stream);
stream.flush();
stream.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
I am able to read them in a file browser (ddms) and can confirm they appear to have been written.
However, any attempt to load the images results in non-null bitmaps with width and height of -1. I am using the following code to load them:
imageList = getFilesDir().list();
Bitmap bmp = null;
for(String img : imageList)
{
try {
bmp = BitmapFactory.decodeStream(openFileInput(img));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
EDIT: On further inspection, it seems, after conversion the images are of density 160 (and not 240 as they should be) also, after testing a working application it seems the -1 mWidth and -1 mHeight on the bitmaps is irrelevent.
I had same problem.my data folder given smallest image.and cursor return null pointer exception on my getDestination method.then i fixed like it
public void captureNewPhoto() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
targetFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
targetUri = Uri.fromFile(targetFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT, targetUri);
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
startActivityForResult(intent, 12);
}
And i use like in onActivityResult();
BitmapFactory.Options options = new BitmapFactory.Options();
networkBitmap = BitmapFactory.decodeFile(targetUri.getPath(),
options);
//ImageDialog(networkBitmap);
//String path = getRealPathFromUri(this, Uri.parse(targetUri.getPath()));
String myDeviceModel = android.os.Build.MODEL;
deviceName = Build.MANUFACTURER;
if (myDeviceModel.equals("GT-I9500")) {
} else if (deviceName.contains("samsung")) {
} else {
exif = ReadExif(targetUri.getPath());
if (exif.equals("6")) {
matrixx.postRotate(90);
} else if (exif.equals("7")) {
matrixx.postRotate(-90);
} else if (exif.equals("8")) {
matrixx.postRotate(-90);
} else if (exif.equals("5")) {
matrixx.postRotate(-90);
}
//matrixx.postRotate(-90);
}
networkBitmap = Bitmap.createBitmap(networkBitmap, 0, 0, networkBitmap.getWidth(), networkBitmap.getHeight(), matrixx, true);
Log.e("Taget File ", "Size " + targetFile.length());
if (networkBitmap != null) {
ImageSetting(networkBitmap, System.currentTimeMillis() + filename);
}
public void ImageSetting(Bitmap imageBitmap, final String fileName) {
networkBitmap = imageBitmap;
organizator(networkBitmap, fileName);
networkBitmap = null;
}` public void tamamlandiOndenFoto(Bitmap turnedBitmap, String filename) {
frontFotoFile = storeBitmap(networkBitmap, filename);
ondenFotoPath = ondenFoto.getAbsolutePath();
ondenFotoImageView.setImageBitmap(turnedBitmap);
}`
public File storeBitmap(Bitmap bp, String fileName) {
File sd = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File dest = new File(sd, fileName);
if (bp != null) {
try {
FileOutputStream out = new FileOutputStream(dest);
bp.compress(Bitmap.CompressFormat.PNG, 100, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
Log.e("Alinan hata ", " Catch hata ", e);
}
return dest;
} else {
return null;
}
}
I hope give you any idea for your problem.

Categories

Resources