How to use readFileToByteArray with image from gallery - java

I'm trying to implement in my app the haystack.ai API. I read the documentation. I need help to change something in my code.
In the example code in the documentation, you provide the path of your image. I need to let the user choose a picture from the gallery(I know how to do that) and then convert the picture into an array of byte.
That's what I tried:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_rate);
backBtn = findViewById(R.id.back_btn);
image = findViewById(R.id.imageRated);
if (getIntent().getExtras() != null) {
imageUri = Uri.parse(getIntent().getStringExtra("uri"));
image.setImageURI(imageUri);
}
backBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(RateActivity.this, MainActivity.class);
startActivity(intent);
}
});
try {
getScore();
} catch (IOException e) {
e.printStackTrace();
}
}
public void getScore() throws IOException {
URL url = new URL("https://api.haystack.ai/api/image/analyze?output=json&apikey=myapikey");
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
byte[] imageData = FileUtils.readFileToByteArray(new File(imageUri.toString()));
OutputStream os = new BufferedOutputStream(conn.getOutputStream());
os.write(imageData);
os.close();
InputStream is = conn.getInputStream();
byte[] buffer = new byte[1024];
ByteArrayOutputStream responseBuffer = new ByteArrayOutputStream();
while (true) {
int n = is.read(buffer, 0, buffer.length);
if (n <= 0) {
break;
}
responseBuffer.write(buffer, 0, n);
}
String response = responseBuffer.toString("UTF-8");
Log.v("Score", response);
}
}
The logcat says :
RateActivity.getScore(Unknown Source:12) at line 62 --->
byte[] imageData = FileUtils.readFileToByteArray(new File(imageUri.toString()));
I also tried:
byte[] imageData = FileUtils.readFileToByteArray(new File(imageUri.getPath()));
The original code in the documentation is:
byte[] imageData = Files.readAllBytes(Paths.get("testImage4.jpg"));
I need to convert the selected picture for the imageData array.
How can I do that?

From your question it seems that you want to convert image URI to
byteArray.
If it is the case you can try the code below.
public void convertUriToByteArray(String uri)
{
ByteArrayOutputStream bArray = new ByteArrayOutputStream();
FileInputStream fIn = null;
try {
fIn = new FileInputStream(new File(uri));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
byte[] buf = new byte[1024];
int n;
try {
while (-1 != (n = fIn.read(buf)))
bArray.write(buf, 0, n);
} catch (IOException e) {
e.printStackTrace();
}
byte[] bytes = bArray.toByteArray();
}

Related

When i select image from recent then image is broken in android | Multiple images from recent

This error occurs mostly times when select images from recent folder
class com.bumptech.glide.load.engine.GlideException: Received null model
Call multiple images select
Sample Preview
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/*");
i.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
*gallery*.launch(i);
gallery basically startActivityForResult(i,123) and OnActivityResult method is deprecated, the gallery is alternative which is defined below
ActivityResultLauncher<Intent> gallery = choosePhotoFromGallery();
and choosePhotoFromGallery() is method which is define below
private ActivityResultLauncher<Intent> choosePhotoFromGallery() {
return registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
result -> {
try {
if (result.getResultCode() == RESULT_OK) {
if (null != result.getData()) {
if (result.getData().getClipData() != null) {
ClipData mClipData = result.getData().getClipData();
for (int i = 0; i < mClipData.getItemCount(); i++) {
ClipData.Item item = mClipData.getItemAt(i);
Uri uri = item.getUri();
String imageFilePathColumn = getPathFromURI(this, uri);
productImagesList.add(imageFilePathColumn);
}
} else {
if (result.getData().getData() != null) {
Uri mImageUri = result.getData().getData();
String imageFilePathColumn = getPathFromURI(this, mImageUri);
productImagesList.add(imageFilePathColumn);
}
}
} else {
showToast(this, "You haven't picked Image");
productImagesList.clear();
}
} else {
productImagesList.clear();
}
} catch (Exception e) {
e.printStackTrace();
showToast(this, "Something went wrong");
productImagesList.clear();
}
});
}
and getPathFromURI() is method which define below
public String getPathFromURI(Context context, Uri contentUri) {
OutputStream out;
File file = getPath();
try {
if (file.createNewFile()) {
InputStream iStream = context != null ? context.getContentResolver().openInputStream(contentUri) : context.getContentResolver().openInputStream(contentUri);
byte[] inputData = getBytes(iStream);
out = new FileOutputStream(file);
out.write(inputData);
out.close();
return file.getAbsolutePath();
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
private byte[] getBytes(InputStream inputStream) throws IOException {
ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
int len = 0;
while ((len = inputStream.read(buffer)) != -1) {
byteBuffer.write(buffer, 0, len);
}
return byteBuffer.toByteArray();
}
and the getPath() is
private File getPath() {
File folder = new File(Environment.getExternalStorageDirectory(), "Download");
if (!folder.exists()) {
folder.mkdir();
}
return new File(folder.getPath(), System.currentTimeMillis() + ".jpg");
}
THANK YOU IN ADVANCE HAPPY CODING

How to convert Uri image into Base64?

I have write code to convert image from file location into base64. I can easily convert image into base64 from absolute file location like: C:/Users/Java Engineer/Desktop/test/gallery/magar/Kanuglam.jpg , but I can not convert from location like
. I want to convert image to use in android from web-service.
Here is code sample :
/**
* TEST JSON
*/
String convertToJsonArrayWithImageForMovieDetailTest(ResultSet rs) {
System.out.println("I am insied json converter");
JSONArray list = new JSONArray();
JSONObject obj ;
//File file;
File locatedFile;
FileInputStream fileInputStream;
try {
while (rs.next()) {
obj = new JSONObject();
System.out.println("inside RS");
System.out.println("date is there ha ha ");
obj.put("movie_name", rs.getString("name"));
obj.put("movie_gener", rs.getString("type"));
String is_free_stuff = rs.getString("is_free_stuff");
if (is_free_stuff == "no") {
is_free_stuff = "PAID";
} else {
is_free_stuff = "FREE";
}
obj.put("movie_type", is_free_stuff);
//String movie_image = rs.getString("preview_image");
//this does not work
String movie_image = "http://www.hamropan.com/stores/slider/2016-09-10-852311027.jpg";
//this works for me
// file = new File("C:/Users/Java Engineer/Desktop/Nike Zoom Basketball.jpg");
locatedFile = new File(movie_image);
// Reading a Image file from file system
fileInputStream = new FileInputStream(locatedFile);
if (locatedFile == null) {
obj.put("movie_image", "NULL");
} else {
byte[] iarray = new byte[(int) locatedFile.length()];
fileInputStream.read(iarray);
byte[] img64 = com.sun.jersey.core.util.Base64
.encode(iarray);
String imageString = new String(img64);
obj.put("movie_image", imageString);
}
list.add(obj);
}
} catch (Exception e) {
e.printStackTrace();
}
return list.toString();
}
this block of code works for me but it seem slow
public String imageConvertMethod(String url) throws Exception{
ByteArrayOutputStream output = new ByteArrayOutputStream();
try (InputStream input = new URL(url).openStream()) {
byte[] buffer = new byte[512];
for (int length = 0; (length = input.read(buffer)) > 0;) {
output.write(buffer, 0, length);
}
}
byte [] byte_array = output.toByteArray();
byte[] img64 = com.sun.jersey.core.util.Base64
.encode(byte_array);
String imageString = new String(img64);
return imageString;
}
Ok, try this
bitmap = getBitmapFromUrl(image_url);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
byte[] array = stream.getByteArray();
encoded_string = Base64.encodeToString(array, 0);
Method wo load image from url
public static Bitmap getBitmapFromURL(String src) {
try {
URL url = new URL(src);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap myBitmap = BitmapFactory.decodeStream(input);
return myBitmap;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
#thanks to Fabio Venturi Pastor
Try this:
ImageUri to Bitmap:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == TAKE_PHOTO_CODE && resultCode == RESULT_OK) {
final Uri imageUri = data.getData();
final InputStream imageStream = getContentResolver().openInputStream(imageUri);
final Bitmap selectedImage = BitmapFactory.decodeStream(imageStream);
String encodedImage = encodeImage(selectedImage);
}
}
Encode Bitmap in base64
private String encodeImage(Bitmap bm)
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.JPEG,100,baos);
byte[] b = baos.toByteArray();
String encImage = Base64.encodeToString(b, Base64.DEFAULT);
return encImage;
}
Encode from FilePath to base64
private String encodeImage(String path)
{
File imagefile = new File(path);
FileInputStream fis = null;
try{
fis = new FileInputStream(imagefile);
}catch(FileNotFoundException e){
e.printStackTrace();
}
Bitmap bm = BitmapFactory.decodeStream(fis);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.JPEG,100,baos);
byte[] b = baos.toByteArray();
String encImage = Base64.encodeToString(b, Base64.DEFAULT);
//Base64.de
return encImage;
}
output:
reference :
Take picture and convert to Base64

Android copy file from internal storage to external

I am trying to Copy file from internal memory card to external memory card
By googling i found this answer
try {
InputStream in = new FileInputStream("/storage/sdcard1/bluetooth/file7.zip"); // Memory card path
File myFile = new File("/storage/sdcard/"); //
OutputStream out = new FileOutputStream(myFile);
// Copy the bits from instream to outstream
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
session.showToast("file copied sucessfully");
} catch (FileNotFoundException e) {
showToast(e.getMessage());
e.printStackTrace();
} catch (IOException e) {
showToast(e.getMessage());
e.printStackTrace();
}
its work for internal move to internal or external storage to external
but cross transferring do not work its throws an error Erofs read only file system
Try some thing like this:
new FileAsyncTask().execute(files);
and
// AsyncTask for Background Process
private class FileAsyncTask extends AsyncTask<ArrayList<String>, Void, Void> {
ArrayList<String> files;
ProgressDialog dialog;
#Override
protected void onPreExecute() {
dialog = ProgressDialog.show(ActivityName.this, "Your Title", "Loading...");
}
#Override
protected Void doInBackground(ArrayList<String>... params) {
files = params[0];
for (int i = 0; i < files.size(); i++) {
copyFileToSDCard(files.get(i));
} return null;
}
#Override
protected void onPostExecute(Void result) {
dialog.dismiss();
}
}
// Function to copy file to the SDCard
public void copyFileToSDCard(String fileFrom){
AssetManager is = this.getAssets();
InputStream fis;
try {
fis = is.open(fileFrom);
FileOutputStream fos;
if (!APP_FILE_PATH.exists()) {
APP_FILE_PATH.mkdirs();
}
fos = new FileOutputStream(new File(Environment.getExternalStorageDirectory()+"/MyProject", fileFrom));
byte[] b = new byte[8];
int i;
while ((i = fis.read(b)) != -1) {
fos.write(b, 0, i);
}
fos.flush();
fos.close();
fis.close();
}
catch (IOException e1) {
e1.printStackTrace();
}
}
public static boolean copyFile(String from, String to) {
try {
int bytesum = 0;
int byteread = 0;
File oldfile = new File(from);
if (oldfile.exists()) {
InputStream inStream = new FileInputStream(from);
FileOutputStream fs = new FileOutputStream(to);
byte[] buffer = new byte[1444];
while ((byteread = inStream.read(buffer)) != -1) {
bytesum += byteread;
fs.write(buffer, 0, byteread);
}
inStream.close();
fs.close();
}
return true;
} catch (Exception e) {
return false;
}
}
Try this, Replace this line:
File myFile = new File("/storage/sdcard/");
with:
ContextWrapper cw = new ContextWrapper(getApplicationContext());
// path to /data/data/yourapp/app_data/imageDir
File myFile = cw.getDir("imageDir", Context.MODE_PRIVATE);
Check this link, may be helpfull: click here

Monitoring BufferedInputStream download progress

I'm trying to download a file using an AsyncTask on Android. I want to display a ProgressDialog which should have a progress bar to show the status of the download. I'm using the onProgressUpdate() function for that and implemented a call to publishProgress() in my doInBackground() function. However, the progress dialog only pops up after downloading the file. My code:
protected Long doInBackground(URL...urls) {
for (int i = 0; i < urls.length; i++) {
url = urls[i];
try {
URLConnection conn = url.openConnection();
conn.connect();
totalSize = conn.getContentLength();
BufferedInputStream bis = new BufferedInputStream(url.openStream());
FileOutputStream fos = new FileOutputStream(Environment.getExternalStorageDirectory().getPath() + "/forvo_temp.mp3");
BufferedOutputStream bos = new BufferedOutputStream(fos,1024);
byte [] data = new byte[1024];
int x=0; int c=0;
while((x=bis.read(data,0,1024))>=0){
bos.write(data,0,x);
c += 1024;
publishProgress(c);
}
} catch (Exception e) {
e.printStackTrace();
}
}
return 0L; // Don't know what to do with this
}
protected void onProgressUpdate(Integer...args) {
pd = ProgressDialog.show(context, "Downloading...", "Downloading...", true, false);
pd.setProgress(args[0] / totalSize);
}
I guess the whole file is downloaded when I call new BufferedInputStream(url.openStream()). How can I monitor the download progress?
Wrap URL input stream with you own InputStream that just reads bytes and "monitors" the status, e.g. sends notifications.
It is simple: InputStream is an abstract class with only one abstract method:
public abstract int read() throws IOException;
In your case it should read bytes from stream that it wraps.
public class NotifcationInputStream extends InputStream {
private InputStream in;
private int count;
private Collection<ByteListener> listeners = new ArrayList<ByteListener>();
NotificationInputStream(InputStream in) {
this.in = in;
}
public int read() throws IOException {
int b = in.read();
byteReceived(b);
return b;
}
public void addListener(ByteListener listener) {
listeners.add(listener);
}
private void byteReceived(int b) {
for (ByteListener l : listeners) {
l.byteReceived(b, ++count);
}
}
}
public interface ByteListener extends EventListener {
public void byteReceived(int b, int count);
}
The problem here is how to show the process bar: you have to know total number of bytes. You can get it from HTTP header content-length if your resource is static. Otherwise you need appropriate server support or heuristics.
This code is useful showing download items totol size and downloaded size.
private static final int DOWNLOAD_ONPROGRESS = 1;
#Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case DOWNLOAD_ONPROGRESS:
progressDialog = new ProgressDialog(this);
progressDialog.setMessage("Downloading latest ...");
progressDialog.setCancelable(true);
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
try {
progressDialog.show();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return progressDialog;
default:
return null;
}
}
You can use AsyncTask for downloading the version in background.
private class DownLoad extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
logger.info("LoadDataAsync onPreExecute");
showDialog(DOWNLOAD_ONPROGRESS);
}
#Override
protected String doInBackground(String... aurl) {
int count = 0;
try {
URL url = new URL(aurl[0]);
URLConnection urlConnection = url.openConnection();
urlConnection.connect();
int contentlength = urlConnection.getContentLength();
progressDialog.setMax(contentlength);
String PATH = "";
File file = null;
if (android.os.Environment.getExternalStorageState().equals(
android.os.Environment.MEDIA_MOUNTED)) {
PATH = Environment.getExternalStorageDirectory()
+ "/download/";
file = new File(PATH);
file.mkdirs();
File outputFile = new File(file, "telfaz.apk");
OutputStream fos = new FileOutputStream(outputFile);
InputStream is = new BufferedInputStream(url.openStream());
byte[] buffer = new byte[1024];
long len1 = 0;
while ((count = is.read(buffer)) != -1
&& !downLoad.isCancelled()) {
len1 += count;
publishProgress("" + len1);
fos.write(buffer, 0, count);
}
fos.flush();
fos.close();
is.close();
}
logger.info("Success -> file downloaded succesfully. returning 'success' code");
return Util.APK_DOWNLOAD_SUCCESS;
} catch (IOException e) {
logger.error("Exception in update process : "
+ Util.getStackTrace(e));
}
logger.info("Failed -> file download failed. returning 'error' code");
return Util.APK_DOWNLOAD_FAILED;
}
#Override
protected void onPostExecute(String result) {
logger.info("on DownLoad onPostExecute. result : " + result);
progressDialog.dismiss();
removeDialog(DOWNLOAD_ONPROGRESS);
if (result.equalsIgnoreCase(Util.APK_DOWNLOAD_SUCCESS)) {
Update();
} else {
Toast.makeText(DownloadAllContentsActivity.this,
getString(R.string.updateApplicationFailed),
Toast.LENGTH_LONG).show();
loadDataAsync.execute();
}
}
#Override
protected void onProgressUpdate(String... values) {
if (values != null && values.length > 0) {
progressDialog.setProgress(Integer.parseInt(values[0]));
}
}
}

Android: Sharing an image from raw folder. Wrong image being shared

I have an Activity where the user can share an image from the raw folder.
The raw folder has 70 images, all named alphabetically. The first one is R.raw.recipe01 and the last is R.raw.recipe70.
I get the image int I would like to share from a Bundle and I have a method which copies the image from the raw folder to a accessible file.
I call startActivity(createShareIntent()); in the ActionBar MenuItem, which works successfully.
PROBLEM
The share intent will always select R.raw.recipe01 as the image, even if the int from the Bundle is for image for exmaple R.raw.recipe33.
I have shared my code below. Can anyone spot what I am doing wrong?
CODE:
private int rawphoto = 0;
private static final String SHARED_FILE_NAME = "shared.png";
#Override
public void onCreate(Bundle savedInstanceState) {
Bundle bundle = getIntent().getExtras();
rawphoto = bundle.getInt("rawphoto");
int savedphoto = rawphoto;
// COPY IMAGE FROM RAW
copyPrivateRawResourceToPubliclyAccessibleFile(savedphoto);
private Intent createShareIntent() {
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("image/*");
shareIntent.putExtra(Intent.EXTRA_TEXT, "IMAGE TO SHARE: ");
Uri uri = Uri.fromFile(getFileStreamPath("shared.png"));
shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
return shareIntent;
}
private void copyPrivateRawResourceToPubliclyAccessibleFile(int photo) {
System.out.println("INT PHOTO: " +photo);
InputStream inputStream = null;
FileOutputStream outputStream = null;
try {
inputStream = getResources().openRawResource(photo);
outputStream = openFileOutput(SHARED_FILE_NAME,
Context.MODE_WORLD_READABLE | Context.MODE_APPEND);
byte[] buffer = new byte[1024];
int length = 0;
try {
while ((length = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, length);
}
} catch (IOException ioe) {
/* ignore */
}
} catch (FileNotFoundException fnfe) {
/* ignore */
}
finally {
try {
inputStream.close();
} catch (IOException ioe) {
}
try {
outputStream.close();
} catch (IOException ioe) {
}
}
}
Remove Context.MODE_APPEND so that the file gets overwritten if it already exists.

Categories

Resources