Saving RelativeLayout as bitmap - android

I'm trying to save a RelativeLayout as a bitmap and insert it into the gallery, the code below throws this exception:
java.lang.NullPointerException
at java.io.File.<init>(File.java:282)
at maa.Fragements.ColorPaletteFragment.galleryAddPic(ColorPaletteFragment.java:344)
because the parameter imagePath of galleryAddPic method is empty or null
insert Image to gallery:
private void galleryAddPic(String imagePath) {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(imagePath);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
getActivity().sendBroadcast(mediaScanIntent);
}
saving the image:
#SuppressLint("StaticFieldLeak")
public class saveViewAsBitmap extends AsyncTask<RelativeLayout, String, String> {
#SuppressLint("SetTextI18n")
#Override
protected void onPreExecute() {
super.onPreExecute();
txt.setText("Saving image to gallery ...");
}
#Override
protected String doInBackground(RelativeLayout... relatives) {
String savedImagePath = null;
String imageFileName = "inColor" + System.currentTimeMillis() + ".png";
Bitmap image = getBitmapFromView(relatives[0]);
File storageDir = new File(
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
+ "/inColor Folder");
boolean success = true;
if (!storageDir.exists()) {
success = storageDir.mkdirs();
}
if (success) {
File imageFile = new File(storageDir, imageFileName);
savedImagePath = imageFile.getAbsolutePath();
try {
OutputStream fOut = new FileOutputStream(imageFile);
image.compress(Bitmap.CompressFormat.PNG, 100, fOut);
fOut.close();
} catch (Exception e) {
e.printStackTrace();
}
dialogLoading.dismiss();
}
return savedImagePath;
}
#Override
protected void onPostExecute(String path) {
super.onPostExecute(path);
galleryAddPic(path);
}
}
can anyone help me to get resolve this issue?

Make sure that you have
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
in Manifest file

Related

Cannot save Bitmap image to Phone's Storage in Android

So, I am creating a QRCode generator application in which user can generate QR code from the data they have entered.I can successfully generate the QR code and show it to the imageview on a Button click but I am facing issue when I tried to save that QR code to my phone's storage (or gallery).
On this button click, QRGenerator function will be called and It will generate the QR code from the Edittext data.
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
QRGenerator();
}
});
Here is the QRGenerator() funcion :
private void QRGenerator() {
String data = text.getText().toString();
MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
try {
BitMatrix bitMatrix = multiFormatWriter.encode(data, BarcodeFormat.QR_CODE, 300, 300);
BarcodeEncoder barcodeEncoder = new BarcodeEncoder();
Bitmap bitmap = barcodeEncoder.createBitmap(bitMatrix);
imgView.setImageBitmap(bitmap);
bitmap2 = ((BitmapDrawable)imgView.getDrawable()).getBitmap();
saveImg.setVisibility(View.VISIBLE);
} catch (WriterException e) {
e.printStackTrace();
}
}
and from here I can call the save image function :
saveImg.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
saveImageFunction(bitmap2);
}
});
and here my issue arise, I have put a Toast to notify when my image will saved to gallery but it never pops up
Here is the saveImageFunction :
private void saveImageFunction(Bitmap bitmap) {
String savedImagePath = null;
String imageFileName = "JPEG_" + "test" + ".jpg";
File storageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)+ "/Demo");
boolean success = true;
if(!storageDir.exists()){
success = storageDir.mkdirs();
}
if(success){
File imageFile = new File(storageDir, imageFileName);
savedImagePath = imageFile.getAbsolutePath();
try {
OutputStream fOut = new FileOutputStream(imageFile);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fOut);
fOut.close();
} catch (Exception e) {
e.printStackTrace();
}
addToGallery(savedImagePath);
Toast.makeText(MainActivity.this,"Saved to Gallery!",Toast.LENGTH_SHORT).show();
}
}
and to put that saved image to gallery I have used this function :
addToGallery() :
private void addToGallery(String imagePath){
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(imagePath);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
sendBroadcast(mediaScanIntent);
}
As per Gk Mohammad Emon says, I tried adding Toast as well as Log.d in my catch method of SaveImage function but nothing pops up neither on Screen nor in LogCat (Please address any type of mistake if there) :
private void saveImageFunction(Bitmap bitmap) {
String savedImagePath = null;
String imageFileName = "JPEG_" + "test" + ".jpg";
File storageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)+ "/Demo");
boolean success = true;
if(!storageDir.exists()){
success = storageDir.mkdirs();
}
if(success){
File imageFile = new File(storageDir, imageFileName);
savedImagePath = imageFile.getAbsolutePath();
try {
OutputStream fOut = new FileOutputStream(imageFile);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fOut);
Toast.makeText(MainActivity.this,"Image Saved!", Toast.LENGTH_SHORT).show();
fOut.close();
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(MainActivity.this,"hello There",Toast.LENGTH_SHORT).show();
Log.d("Exception e",e.toString());
}
addToGallery(savedImagePath);
Toast.makeText(MainActivity.this,"Saved to Gallery!",Toast.LENGTH_SHORT).show();
}
}

Android File Not Found Exception, though the image is saved

I am making an app which utilizes the camera, and has the ability to take a picture to use a simple image recognition API on it. I can use the gallery just fine to upload images, but straight from the camera is giving me massive issues. I have basically just copied the android dev documentation for most of the image creation, though may have needed to change some items here and there.
Here is the total code:
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + "Image_for_Stack" + "_";
File storageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DCIM), "Camera");
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
currentPhotoPath = "file: " + image.getAbsolutePath();
return image;
}
private void dispatchTakePictureIntent() {
try {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(getActivity().getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
Log.v(TAG, "IO Exception " + ex);
}
// Continue only if the File was successfully created
if (photoFile != null) {
photoURI = FileProvider.getUriForFile(getContextOfApplication(),
BuildConfig.APPLICATION_ID + ".provider",
photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(takePictureIntent, IMAGE_CAPTURE);
}
}
} catch (Exception e) {
Log.v(TAG, "Exception in dispatch " + e);
}
}
private void galleryAddPic() {
try {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(currentPhotoPath);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
getContextOfApplication().sendBroadcast(mediaScanIntent);
} catch (Exception e) {
Log.v(TAG, "Exception " + e);
}
}
And in a separate class, this is called:
public static byte[] getByteArrayFromIntentData(#NonNull Context context, #NonNull Intent data) {
InputStream inStream = null;
Bitmap bitmap = null;
try {
inStream = context.getContentResolver().openInputStream(data.getData());
Log.v(TAG, "Instream works");
bitmap = BitmapFactory.decodeStream(inStream);
final ByteArrayOutputStream outStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
return outStream.toByteArray();
} catch (FileNotFoundException e) {
Log.v("FileOP Debug", "Exception " + e);
return null;
} finally {
if (inStream != null) {
try {
inStream.close();
} catch (IOException ignored) {
}
}
if (bitmap != null) {
bitmap.recycle();
}
}
}
Now, the image is created without issue. I can go to the emulator, look through the photo's app, and get:
.
However, I get this error when the code gets to giving inStream a value:
java.io.FileNotFoundException: /file:
/storage/emulated/0/DCIM/Camera/JPEG_Image_for_Stack_3248071614992872091.jpg
(No such file or directory) .
I don't exactly understand how this could be. The item clearly exists, and is saved on the phone. The app does request and is given the permission to write to external storage, and I have checked in the emulator permissions that it is given. Write also comes with read, so that shouldn't be an issue as far as I'm aware either.
Edit
To show where this code is being called from.
else if (requestCode == IMAGE_CAPTURE) {
galleryAddPic();
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(currentPhotoPath);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
final ProgressDialog progress = new ProgressDialog(getContextOfApplication());
progress.setTitle("Loading");
progress.setMessage("Identify your flower..");
progress.setCancelable(false);
progress.show();
if (!CheckNetworkConnection.isInternetAvailable(getContextOfApplication())) {
progress.dismiss();
Toast.makeText(getContextOfApplication(),
"Internet connection unavailable.",
Toast.LENGTH_SHORT).show();
return;
}
client = ClarifaiClientGenerator.generate(API_KEY);
final byte[] imageBytes = FileOp.getByteArrayFromIntentData(getContextOfApplication(), mediaScanIntent);
As of right now, imageBytes will be null as the the FileNotFound exception is thrown on that method call.
You can try this code...
public class Images extends Activity
{
private Uri[] mUrls;
String[] mFiles=null;
public void onCreate(Bundle icicle)
{
super.onCreate(icicle);
setContentView(R.layout.images);
File images = Environment.getDataDirectory();
File[] imagelist = images.listFiles(new FilenameFilter(){
#override
public boolean accept(File dir, String name)
{
return ((name.endsWith(".jpg"))||(name.endsWith(".png"))
}
});
mFiles = new String[imagelist.length];
for(int i= 0 ; i< imagelist.length; i++)
{
mFiles[i] = imagelist[i].getAbsolutePath();
}
mUrls = new Uri[mFiles.length];
for(int i=0; i < mFiles.length; i++)
{
mUrls[i] = Uri.parse(mFiles[i]);
}
Gallery g = (Gallery) findViewById(R.id.gallery);
g.setAdapter(new ImageAdapter(this));
g.setFadingEdgeLength(40);
}
public class ImageAdapter extends BaseAdapter{
int mGalleryItemBackground;
public ImageAdapter(Context c) {
mContext = c;
}
public int getCount(){
return mUrls.length;
}
public Object getItem(int position){
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent){
ImageView i = new ImageView(mContext);
i.setImageURI(mUrls[position]);
i.setScaleType(ImageView.ScaleType.FIT_XY);
i.setLayoutParams(new Gallery.LayoutParams(260, 210));
return i;
}
private Context mContext;
}
}

How to Save image into local storage loaded with Glide?

I have an ImageView in which I loaded a photo from server into it with Glide library.
I have a save button in which I want the image saved to gallery and internal storage when clicked after being loaded. I have tried several possibilities with no success as nothing seem to happen after I click the button.
public class ImagePreviewActivity extends AppCompatActivity {
ImageView imageView;
final File myDir = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/SmartPhoto");
boolean success = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_image_preview);
imageView = findViewById(R.id.image_preview);
saveImage();
}
private void saveImage() {
TextView mSave = findViewById(R.id.save_img);
mSave.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final Random generator = new Random();
int n = 10000;
n = generator.nextInt(n);
final String fname = "image" + n + ".png";
myDir.mkdirs();
File image = new File(myDir, fname);
imageView.setDrawingCacheEnabled(true);
Bitmap bitmap = imageView.getDrawingCache();
// Encode the file as a PNG image.
FileOutputStream outStream;
try {
outStream = new FileOutputStream(image);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outStream);
/* 100 to keep full quality of the image */
outStream.flush();
outStream.close();
success = true;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
if (success) {
Toast.makeText(getApplicationContext(),"Saved", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(),"not saved", Toast.LENGTH_LONG).show();
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
final Intent scanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
final Uri contentUri = Uri.fromFile(image);
scanIntent.setData(contentUri);
sendBroadcast(scanIntent);
} else {
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://mnt/sdcard/" + Environment.getExternalStorageDirectory())));
}
}
});
}
}
Log Cat
02-24 14:40:41.288 1567-1575/? E/System: Uncaught exception thrown by finalizer
02-24 14:40:41.289 1567-1575/? E/System: java.lang.IllegalStateException: Binder has been finalized!
at android.os.BinderProxy.transactNative(Native Method)
at android.os.BinderProxy.transact(Binder.java:622)
at android.net.INetworkStatsSession$Stub$Proxy.close(INetworkStatsSession.java:476)
at android.app.usage.NetworkStats.close(NetworkStats.java:382)
at android.app.usage.NetworkStats.finalize(NetworkStats.java:118)
at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:223)
at java.lang.Daemons$FinalizerDaemon.run(Daemons.java:210)
at java.lang.Thread.run(Thread.java:761)
AsyncTask, can be used to download Image .This proccess will be in background thread.
class DownloadImage extends AsyncTask<String,Integer,Long> {
String strFolderName;
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Long doInBackground(String... aurl) {
int count;
try {
URL url = new URL((String) aurl[0]);
URLConnection conexion = url.openConnection();
conexion.connect();
String targetFileName="Name"+".rar";//Change name and subname
int lenghtOfFile = conexion.getContentLength();
String PATH = Environment.getExternalStorageDirectory()+ "/"+downloadFolder+"/";
File folder = new File(PATH);
if(!folder.exists()){
folder.mkdir();//If there is no folder it will be created.
}
InputStream input = new BufferedInputStream(url.openStream());
OutputStream output = new FileOutputStream(PATH+targetFileName);
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
} catch (Exception e) {}
return null;
}
protected void onPostExecute(String result) {
}
}
You can call this class like this new DownloadImage().execute(“yoururl”);
Don't forget to add these permissions in manifest file
<uses-permission android:name="android.permission.INTERNET"> </uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
//out oncreate
final File myDir = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/SmartPhoto");
boolean success = false;
//inside oncreate
mSave = (TextView) findViewById(R.id.save);
imageView = (ImageView) findViewById(R.id.header_cover_image);
mSave.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view)
{
saveImage();
}
});
public void saveImage()
{
final Random generator = new Random();
int n = 10000;
n = generator.nextInt(n);
final String fname = "image" + n + ".png";
myDir.mkdirs();
File image = new File(myDir, fname);
imageView.setDrawingCacheEnabled(true);
Bitmap bitmap = imageView.getDrawingCache();
// Encode the file as a PNG image.
FileOutputStream outStream;
try {
outStream = new FileOutputStream(image);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outStream);
/* 100 to keep full quality of the image */
outStream.flush();
outStream.close();
success = true;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
if (success) {
Toast.makeText(getApplicationContext(),"Saved", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(),"not saved", Toast.LENGTH_LONG).show();
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
final Intent scanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
final Uri contentUri = Uri.fromFile(image);
scanIntent.setData(contentUri);
sendBroadcast(scanIntent);
} else {
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://mnt/sdcard/" + Environment.getExternalStorageDirectory())));
}
}

Android.Downloaded image changes transparency

I face a problem when downloading an image from remote server. The image is initially transparent but when I download it the transparency changes into a black background.
Callable.invoke(new Callable<Response>() {
#Override
public Response call() throws Exception {
return service.getImage(image);
}
}, new TaskCallback<Response>() {
#Override
public void success(final Response result) {
try {
InputStream in = result.getBody().in();
Bitmap b = BitmapFactory.decodeStream(in);
String mDirectoryPathname = Environment
.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES)+ "/images/";
String timestamp = new SimpleDateFormat("yyyyMMdd'_'HHmmssSSS")
.format(new Date());
String filename = timestamp + ".png";
final Uri uri = ImageDownloadUtils.createDirectoryAndSaveFile(
context,
b,
filename,
mDirectoryPathname);
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void error(Exception e) {
Log.e(TAG, "Error getting image via OAuth.", e);
}
});
Here is the factory method which is called to save the image.
public static Uri createDirectoryAndSaveFile(Context context,
Bitmap imageToSave,
String fileName,
String directoryPathname) {
if (imageToSave == null)
return null;
File directory = new File(directoryPathname);
if (!directory.exists()) {
directory.mkdirs();
}
File file = new File(directory, getTemporaryFilename(fileName));
if (file.exists())
file.delete();
try {
FileOutputStream outputStream = new FileOutputStream(file);
imageToSave.compress(Bitmap.CompressFormat.JPEG,
100,
outputStream);
outputStream.flush();
} catch (Exception e) {
return null;
}
String absolutePathToImage = file.getAbsolutePath();
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, fileName);
values.put(MediaStore.Images.Media.DESCRIPTION, fileName);
values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis());
values.put(MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME,
file.getName().toLowerCase(Locale.US));
values.put("_data",
absolutePathToImage);
ContentResolver cr = context.getContentResolver();
cr.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
return Uri.parse(absolutePathToImage);
}
This is not the problem with image's transparency. When you download an image and view it in Gallery, it is showing the image in an ImageView. That ImageView has a default background of black colour. That's why the transparent part of the downloaded image appears as black.
If you are showing the image in your application, set the background of ImageView to transparent.
android:background="#android:color/transparent"
in XML or
imageView.setBackgroundColor(Color.TRANSPARENT);
through code.
EDIT: If still the problem persists, try this :
InputStream in = result.getBody().in();
Bitmap b = BitmapFactory.decodeStream(in);
String mDirectoryPathname = Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + "/images/";
String timestamp = new SimpleDateFormat("yyyyMMdd'_'HHmmssSSS").format(new Date());
String filename = timestamp + ".png";
try {
File file = new File(mDirectoryPathname, filename);
FileOutputStream outputStream = new FileOutputStream(file);
b.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
outputStream.flush();
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
final Uri uri = Uri.fromFile(file);

Bitmap to File, Not showing in Default Gallery App

I have this snippet, which is creating image from view. File can be seen in file manager and accessible through code, but default android gallery app is not showing them.
Bitmap returnedBitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(),Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(returnedBitmap);
view.draw(canvas);
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
returnedBitmap.compress(Bitmap.CompressFormat.PNG, 100, bytes);
Date now = new Date();
String path = Environment.getExternalStorageDirectory() + File.separator + "Download" + File.separator +now.getTime()+".png";
File f = new File(path);
try {
f.createNewFile();
FileOutputStream fo = new FileOutputStream(f);
fo.write(bytes.toByteArray());
fo.close();
} catch (Exception e) {
}
You need to add the file to the gallery. Try this code from the developer's website:
private void galleryAddPic(String path) {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(path);//your file path
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
this.sendBroadcast(mediaScanIntent);
}
Note make sure that you are not saving in the private memory of the app.
My experience is that to use MediaScanner is better, you can get the URI of the content stored in media database.
static final class PicScanner implements MediaScannerConnectionClient {
#SuppressWarnings("unused")
private static PicScanner mInstance;
private String mFilename;
private String mMimetype;
private MediaScannerConnection mConn;
public static void scan(Context ctx, File file, String mimetype) {
mInstance = new PicScanner (ctx, file, mimetype);
}
private PicScanner (Context ctx, File file, String mimetype) {
this.mFilename = file.getAbsolutePath();
mConn = new MediaScannerConnection(ctx, this);
mConn.connect();
}
#Override
public void onMediaScannerConnected() {
mConn.scanFile(mFilename, mMimetype);
}
#Override
public void onScanCompleted(String path, Uri uri) {
mConn.disconnect();
mInstance = null;
//notifyNewPicSavedLocally(path, uri);
}
}
Usage example:
PicScanner.scan(mContext, picFile, "image/jpeg"); //picFile should be access-able for other process

Categories

Resources