How to get image from gallery in a .jpg file format? - java

I am trying to get image from gallery. It is giving me image as bitmap. I want the image in .jpg file so that I can save file name in my database.
I have followed this tutorial :
http://www.theappguruz.com/blog/android-take-photo-camera-gallery-code-sample
gallery image selected code:
#SuppressWarnings("deprecation")
private void onSelectFromGalleryResult(Intent data) {
Bitmap bm=null;
if (data != null) {
try {
bm = MediaStore.Images.Media.getBitmap(getApplicationContext().getContentResolver(), data.getData());
} catch (IOException e) {
e.printStackTrace();
}
}
Uri selectedImage = data.getData();
String[] filePath = {MediaStore.Images.Media.DATA};
Cursor c = getContentResolver().query(selectedImage, filePath, null, null, null);
c.moveToFirst();
int columnIndex = c.getColumnIndex(filePath[0]);
String picturePath = c.getString(columnIndex);
c.close();
File file = new File(picturePath);// error line
mProfileImage = file;
profile_image.setImageBitmap(bm);
}
I tried this. But I am getting null pointer on file.
Exception :
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'char[] java.lang.String.toCharArray()' on a null object reference
Also I don't want this newly created file to be saved in external storage. This should be a temporary file. How can I do this?
Thank you..

The good news is you're a lot closer to done than you think!
Bitmap bm=null;
if (data != null) {
try {
bm = MediaStore.Images.Media.getBitmap(getApplicationContext().getContentResolver(), data.getData());
} catch (IOException e) {
e.printStackTrace();
}
}
At this point, if bm != null, you have a Bitmap object. Bitmap is Android's generic image object that's ready to go. It's actually probably in .jpg format already, so you just have to write it to a file. you want to write it to a temporary file, so I'd do something like this:
File outputDir = context.getCacheDir(); // Activity context
File outputFile = File.createTempFile("prefix", "extension", outputDir); // follow the API for createTempFile
Regardless, at this point it's pretty easy to write a Bitmap to a file.
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.JPEG, 100, stream); //replace 100 with desired quality percentage.
byte[] byteArray = stream.toByteArray();
Now you have a byte array. I'll leave writing that to a file to you.
If you want the temporary file to go away, see here for more info: https://developer.android.com/reference/java/io/File.html#deleteOnExit()
Bitmap bm=null;
if (data != null) {
try {
bm = MediaStore.Images.Media.getBitmap(getApplicationContext().getContentResolver(), data.getData());
} catch (IOException e) {
e.printStackTrace();
}
}
if (bm != null) { // sanity check
File outputDir = context.getCacheDir(); // Activity context
File outputFile = File.createTempFile("image", "jpg", outputDir); // follow the API for createTempFile
FileOutputStream stream = new FileOutputStream (outputFile, false); // Add false here so we don't append an image to another image. That would be weird.
// This line actually writes a bitmap to the stream. If you use a ByteArrayOutputStream, you end up with a byte array. If you use a FileOutputStream, you end up with a file.
bm.compress(Bitmap.CompressFormat.JPEG, 100, stream);
stream.close(); // cleanup
}
I hope that helps!

Looks like your picturePath is null. That is why you cannot convert the image. Try adding this code fragment to get the path of the selected image:
private String getRealPathFromURI(Uri uri) {
String[] projection = { MediaStore.Images.Media.DATA };
#SuppressWarnings("deprecation")
Cursor cursor = managedQuery(uri, projection, null, null, null);
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
After that, you need to modify your onSelectFromGalleryResult. Remove/disable line String[] filePath = {MediaStore.Images.Media.DATA}; and so on and replace with below.
Uri selectedImageUri = Uri.parse(selectedImage);
String photoPath = getRealPathFromURI(selectedImageUri);
mProfileImage = new File(photoPath);
//check if you get something like this - file:///mnt/sdcard/yourselectedimage.png
Log.i("FilePath", mProfileImage.getAbsolutePath)
if(mProfileImage.isExist()){
//Check if the file is exist.
//Do something here (display the image using imageView/ convert the image into string)
}
Question: What is the reason you need to convert it in .jpg format? Can it be .gif, .png etc?

Related

Pulling a video file from TextureView To Be saved

Currently, I'm building a camera app using camera2 api. I record the video and that file is sent to another activity to make sure we can correct orientation and watch the video. Then the altered video or picture is saved to the device.
When I use a still image it works, because I can pull the bitmap image and then resave the image like this:
public String saveImage() {
//Getting a new file name and file path
//Should we delete these images after were done with them?
File newImageFile = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File newImageFolder = new File(newImageFile, "camera2VideoImage");
if (newImageFolder.exists())
{
newImageFolder.mkdirs();
}
String timestamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String prepend = "Image_" + timestamp + "_";
File imageFile = null;
try {
imageFile = File.createTempFile(prepend, ".jpg", newImageFolder);
} catch (IOException e) {
e.printStackTrace();
}
String newFileName = imageFile.getAbsolutePath();
Bitmap bitmap = ((BitmapDrawable) imageView.getDrawable()).getBitmap();
try {
FileOutputStream fos = new FileOutputStream(newFileName);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
//returning the new file path.
return newFileName;
}
This works, they view the image and have the option to change orientation on the image in case it is messed up and then we resave.
I'm trying to do the same with a video, but not sure how to pull the video from the textureView so I can save again with the corrected orientation as the front facing camera is upside down sometimes depending on the phone.
The recording save method:
public String saveVideo() {
//Getting a new file name and file path
//Should we delete these images after were done with them?
File newVideoFile = getExternalFilesDir(Environment.DIRECTORY_MOVIES);
File newVideoFolder = new File(newVideoFile, "camera2VideoImage");
if (newVideoFolder.exists())
{
newVideoFolder.mkdirs();
}
String timestamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String prepend = "Video_" + timestamp + "_";
File videoFile = null;
try {
videoFile = File.createTempFile(prepend, ".jpg", newVideoFolder);
} catch (IOException e) {
e.printStackTrace();
}
String newFileName = videoFile.getAbsolutePath();
textureView.getBitmap();
FileOutputStream fos = new FileOutputStream(newFileName);
//returning the new file path.
return newFileName;
}
How do I get the corrected video from the texture view and then save it, like the Image method above?
This is not a recommended way; the cost of getBitmap on TextureView is high, and not likely suitable for 30fps video recording.
But if you really want to try, you need to feed the Bitmap to a MediaRecorder; you may be able to use MediaRecorder.getSurface() for that, then lock the Surface Canvas and draw your Bitmap into it.
However, I would not be surprised if the performance is poor, or if the MediaRecorder Surface won't accept RGB Bitmaps.
In general, you want to connect the camera API directly to the MediaRecorder or MediaCodec Surface. If you really need to edit frames in the middle, using the GPU is generally the most performant option, though it's a lot of code to write to do that.
I ended up changing the configuration on the Media Recorder, looks like I was trying to correct other orientation problems and caused this. So under my set up mediaRecorder I did this:
private void setupMediaRecorder() throws IOException {
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mMediaRecorder.setOutputFile(mVideoFileName);
mMediaRecorder.setVideoEncodingBitRate(100000000);
mMediaRecorder.setVideoFrameRate(30);
mMediaRecorder.setVideoSize(mVideoSize.getWidth(),mVideoSize.getHeight());
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
if (cameraCheck.contains("1") && mTotalRotation == 180){
//This corrects problems for the front facing camera when recording, the default settings work, so we do nothing here.
}else {
mMediaRecorder.setOrientationHint(mTotalRotation);
}
mMediaRecorder.prepare();
}
This checks if it is the front-facing camera and the phone is positioned at 180. If it is do nothing for correction, else use the correction.

How to correctly set the Uri of an image from a folder selected by the user to show in an ImageView?

I need to display an image which I know the file name but I don't know the folder, which must be specified by the user.
I use Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE); to get the folder from the user. It returns an Uri with a path along these lines:
content://com.android.externalstorage.documents/tree/primary%3ADownload
Now I need to display an image from this folder in an ImageView. I tried the following:
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(),
Uri.parse(chosenFolder + "/image.png"));
ImageView imageView = findViewById(R.id.imageview);
imageView.setImageBitmap(bitmap);
The first line throws the following exception:
java.lang.IllegalArgumentException: Invalid URI: content://com.android.externalstorage.documents/tree/primary%3ADownload/image.png
Replacing %3A by : doesn't work.
How to correctly set the Uri to display the image?
i think you should use file path and not URI . A content:// Uri does not have to represent a file on the filesystem .
try this :
String filePath = null;
if (chosenFolder != null && "content".equals(chosenFolder.getScheme())) {
Cursor cursor = this.getContentResolver().query(chosenFolder, new String[] { android.provider.MediaStore.Images.ImageColumns.DATA }, null, null, null);
cursor.moveToFirst();
filePath = cursor.getString(0);
cursor.close();
} else {
filePath = chosenFolder.getPath();
}
and then create bitmap with file path :
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(),
Uri.parse(filepath+ "/image.png"));
I managed to achieve what I wanted with an InputStream.
InputStream is = getContentResolver().openInputStream(imageUri);
Bitmap bitmap = BitmapFactory.decodeStream(is);
To work, the imageUri must be an Uri along the lines of:
content://com.android.externalstorage.documents/document/primary:Download/image.png
However, this means you will be accessing files you do not have permission by default. This means you will have to deal with getting permission.
This is not what I wanted so I scrapped this approach.

Image uploading from android to PHP server using retrofit

I am uploading image to server using retrofit. I am encoding image to bitmap and then convert bitmap to string and passing string to PHP. On PHP side I decode image again and then save to server folder.
It works perfectly if I compress image quality to 30 but app crashes and shows null pointer if I set image quality to 100.
Here is my Code:
ResultActivity:
if (requestCode == 1 && null != data) {
Uri selectedImage = data.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(selectedImage,
filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String picturePath = cursor.getString(columnIndex);
// photo = BitmapFactory.decodeFile(picturePath);
profile_photo =
ImageUtils.getInstant().getCompressedBitmap(picturePath);
Uri tempUri = getImageUri(this, profile_photo);
cursor.close();
profile_image.setImageResource(android.R.color.transparent);
Picasso.get()
.load(tempUri)
.resize(150, 150)
.into(profile_image);
profile_image.setScaleType(ImageView.ScaleType.FIT_XY);
profile_image.setPadding(5, 5, 5, 5);
//Bitmap profile_photo = ((BitmapDrawable)
profile_image.getDrawable()).getBitmap();
upload_profileimage();
b.dismiss();
}
Bitmap to string:
public String BitmapTOString(Bitmap bitmap) {
Bitmap bm = bitmap;
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.JPEG, 100, stream);
byte[] byteFormat = stream.toByteArray();
String imgString = Base64.encodeToString(byteFormat, Base64.DEFAULT);
return imgString;
}
Retrofit API call:
call = user_profileimge_interface.profileImage_uplaod(BitmapTOString(profile_photo), user_id);
PHP Code:
$data = $baseurl.'user_profile_pictures/'.$user_id.".JPEG";
file_put_contents($data, base64_decode($profile_picture));
echo json_encode(Array('message' => "image inserted"));
API interface:
#POST("update_profilepic.php")
Call<Profile_Image_updateJson> profileImage_uplaod(#Query("profile_picture") String profileImage,
#Query("user_id") String user_id);
I'd suggest sending bitmap as binary data rather than converting to/from string. For example:
#POST
Call<Profile_Image_updateJson> profileImage_uplaod(#Query("user_id") String user_id, #Body RequestBody body);
and then something like:
requestBody = RequestBody.create(MediaType.parse("image/jpeg"), imageBytes)
call = user_profileimge_interface.profileImage_uplaod(user_id, requestBody);
Try to Perform BitmaptoString() operation in a separate thread, away from the Main UI Thread.
As processing bitmap is too costly if you perform it in the Main UI Thread, the App might crash. Also, you can use Asynctask or Any Background Process to perform costly functions and avoid any costly operations in Main Thread.

How do I compress image when uploading to server?

I have been trying to look at other examples for compression of images. However, I still don't know where and how do I include the codes for compression into. Could anybody help me with this?
public void uploadMultipart() {
//getting name for the image
String name = editText.getText().toString().trim();
//getting the actual path of the image
String path = getPath(filePath);
//Uploading code
try {
String uploadId = UUID.randomUUID().toString();
//Creating a multi part request
new MultipartUploadRequest(this, uploadId, Constants.UPLOAD_URL)
.addFileToUpload(path, "image") //Adding file
.addParameter("name", name) //Adding text parameter to the request
.setNotificationConfig(new UploadNotificationConfig())
.setMaxRetries(2)
.startUpload(); //Starting the upload
} catch (Exception exc) {
Toast.makeText(this, exc.getMessage(), Toast.LENGTH_SHORT).show();
}
}
//method to get the file path from uri
public String getPath(Uri uri) {
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
cursor.moveToFirst();
String document_id = cursor.getString(0);
document_id = document_id.substring(document_id.lastIndexOf(":") + 1);
cursor.close();
cursor = getContentResolver().query(
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
null, MediaStore.Images.Media._ID + " = ? ", new String[]{document_id}, null);
cursor.moveToFirst();
String path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
// Bitmap bmp = BitmapFactory.decodeFile(path);
// ByteArrayOutputStream baos = new ByteArrayOutputStream();
// bmp.compress(Bitmap.CompressFormat.JPEG, 100, baos);
cursor.close();
return path;
}
Here is the code for compress image in Bitmap
Below code for jpeg images
Bitmap bitmap = BitmapFactory.decodeStream(getAssets().open("imagename.png"));
ByteArrayOutputStream out = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out); // you can set as 90 for compress ration
Bitmap decoded = BitmapFactory.decodeStream(new ByteArrayInputStream(out.toByteArray()));
Below code for png images:
Bitmap bitmap= BitmapFactory.decodeStream(getAssets().open("imagename.png"));
ByteArrayOutputStream out = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
Bitmap decoded = BitmapFactory.decodeStream(new ByteArrayInputStream(out.toByteArray()));
Otherwise, Here is code which encode the string and send to server as encoded format image
String encodedString ="";
try {
BitmapFactory.Options options = null;
options = new BitmapFactory.Options();
options.inSampleSize = 1;
bitmap = BitmapFactory.decodeFile(filepath, options);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
// Must compress the Image to reduce image size to make upload easy
bitmap.compress(Bitmap.CompressFormat.PNG, 90, stream);
byte[] byte_arr = stream.toByteArray();
// Encode Image to String
encodedString = Base64.encodeToString(byte_arr, 0);
} catch (Exception e) {
e.printStackTrace();
}
Try to above solution. It will work for me.

load picture from android phone into byte[]

I want to load a picture i have in the smartphone so i can than send it over the internet to a webservice i created.
Here i provide a sample code of what i am trying and not working.
Bitmap bm = BitmapFactory.decodeFile(path);
System.out.println("BITMAP: "+bm != null);
ByteArrayOutputStream buffer = new ByteArrayOutputStream(bm.getWidth() *bm.getHeight());
bm.compress(CompressFormat.JPEG, 100, buffer);
I made sure that bm isn't null with the system out print. I get a NullPointerException in ByteArrayOutputStream. Any suggestions?
Try this. Use file name with the path
String[] files = null;
File path = new File(Environment.getExternalStorageDirectory(),"folder path");
if(path.exists())
{
filename = path.list();
}
for(int i=0; i<count;i++)
{
Bitmap bitmapOrg = BitmapFactory.decodeFile(path.getPath()+"/"+ files[i]);
}

Categories