I want to send an image Bitmap from a c# server to an App in Android Java and I'm having a problem by decoding the file in java.
Te code in c# to decode an image into a string is as follows:
String bildString = ImageToString("C:\\Users\\Public\\Pictures\\Penguins.jpg");
public static string ImageToString(string path){
if (path == null)
throw new ArgumentNullException("path");
System.Drawing.Image im = System.Drawing.Image.FromFile(path);
MemoryStream ms = new MemoryStream();
im.Save(ms, im.RawFormat);
byte[] array = ms.ToArray();
return Convert.ToBase64String(array);
}
The string is transferred; and here comes the error in Java when I want to recover my image:
Bitmap bildAM = StringToBitMap(bildString);
public Bitmap StringToBitMap(String encodedString){
try{
byte[] encodeByte = Base64.decode(encodedString,Base64.DEFAULT);
Bitmap bitmap=BitmapFactory.decodeByteArray(encodeByte, 0, encodeByte.length);
return bitmap;
}catch(Exception e){
e.getMessage();
return null;
}
I receive following Exception:
StackTrace
Related
Firstly, I have to convert the image into Base64 and then calculate the DPI of an image by converting base64 to buffered Image.
Here is some code that I tried and that works well for image.PNG(.png) format but return -1(wrong output) in other formats like(.jpg)...!
But I need this to also work for other formats too.
private static float base64toBuffer(String inputbuffer) throws IOException, ImageReadException{
byte[] Rimage=decodeToImage(inputbuffer);
final org.apache.sanselan.ImageInfo imageInfo = Sanselan.getImageInfo(Rimage);
final int physicalWidthDpi = imageInfo.getPhysicalWidthDpi();
final int physicalHeightDpi = imageInfo.getPhysicalHeightDpi();
return physicalWidthDpi;
}
private static byte[] buffertoByte(String imageString) {
byte[] imageByte;
try {
BASE64Decoder decoder = new BASE64Decoder();
imageByte = decoder.decodeBuffer(imageString);
return imageByte;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
I am using this to function for encoding and decoding a bitmap for storing a photo in MySQL database. I insert the photo as a string and i want to retrive it in my project to display in an CircleImageView.
public String BitMapToString(Bitmap bitmap) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
byte[] b = baos.toByteArray();
return Base64.encodeToString(b, Base64.DEFAULT);
}
public Bitmap StringToBitMap(String encodedString) {
try {
byte[] encodeByte = Base64.decode(encodedString, Base64.DEFAULT);
return BitmapFactory.decodeByteArray(encodeByte, 0, encodeByte.length);
} catch (Exception e) {
e.getMessage();
return null;
}
}
and this is where i call it:
String fotoFromDB = studentFromDB.getFotoStringStudent();
Bitmap bitmap = StringToBitMap(fotoFromDB); //in the debbuger here says that bitmap==null
profilePic.setImageBitmap(bitmap);
String fotoFromDB = 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
The problem is that when i try to transform this code back in bitmap it doesn't work.
I created a C# server that sends an Bitmap through a socket to android client. That Bitmap is constantly updating because it's a video feed.
Server C#
private void send_data() {
ImageConverter converter = new ImageConverter();
byte[] sendBytes = (byte[]) converter.ConvertTo(master.picturebox_master.Image, typeof(byte[]));
string_master_frame = System.Text.Encoding.UTF8.GetString(sendBytes);
string_master_frame = Convert.ToBase64String(sendBytes);
data = string_master_frame + "\n";
tcpServer1.Send(data);
}
Client Android
#Override
protected Void doInBackground(Void... arg0) {
Socket socket = null;
try {
socket = new Socket(dstAddress, dstPort);
Scanner r = new Scanner(new InputStreamReader(socket.getInputStream()));
while (true) {
valores[26] = r.nextLine();
publishProgress(valores[26]);
}
return null;
}
#Override
protected void onProgressUpdate(String... values) {
byte[] decodedString = Base64.decode(values[26], Base64.NO_WRAP);
Bitmap master_bitmap = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
master_frame.setImageBitmap(master_bitmap);
}
The first frame is sent and the Android client displays it correctly. But when the next frame comes, the Android Client Crashes.
Error:
Process: com.example.tiago.java_android, PID: 826
java.lang.IllegalArgumentException: bad base-64
at android.util.Base64.decode(Base64.java:161)
at android.util.Base64.decode(Base64.java:136)
at android.util.Base64.decode(Base64.java:118)
at com.example.tiago.java_android.Cliente.onProgressUpdate(Cliente.java:228)
at com.example.tiago.java_android.Cliente.onProgressUpdate(Cliente.java:28)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:656)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5431)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:914)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:707)
I though the valores[26] data was being corrupted but it's not. I get the data correctly.
I used http://codebeautify.org/base64-to-image-converter to check if I get the data correctly.
Any idea?
PS: I lost my account so I had to make this one.
Bitmap master_bitmap;
byte[] decodedString = Base64.decode(values[26],Base64.NO_WRAP);
master_bitmap = BitmapFactory.decodeByteArray(decodedString,0,decodedString.length);
if(master_bitmap != null)
{
try {
master_frame.setImageBitmap(master_bitmap);
}
catch (IllegalArgumentException e)
{
e.printStackTrace();
}
}
master_bitmap.recycle();
}
Didnt work. Error:
java.lang.RuntimeException: Canvas: trying to use a recycled bitmap
Did you try with try/catch block I explained previously?
Recall:
I had the same problem and I am almost sure this will solve your problem:
String[] safe = values[26].split("=");
byte[] decodedString = Base64.decode(safe[0],Base64.NO_WRAP);
Bitmap master_bitmap = BitmapFactory.decodeByteArray(decodedString,0,decodedString.length);
master_frame.setImageBitmap(master_bitmap);
master_bitmap.recycle(); //THIS LINE WAS ENOUGH TO FIX MY CODE
Also, don't forget to use try/catch blocks effectively.
try{ //code here}
catch(IllegalArgumentException e){ //code here if you want}
(Add more catch statements if necessary.)
My full code for further help:
byte[] bytearray = Base64.decode(dataIn);
Bitmap myBitmap = BitmapFactory.decodeByteArray(bytearray, 0,bytearray.length);
if (myBitmap!=null) {
//some irrelevant code here to turn bitmap to a PImage (a Processing image class)
}
myBitmap.recycle();
This works perfectly for me.
Try also this:
try {
Bitmap master_bitmap;
master_bitmap=BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
if (master_bitmap != null) { //might be an unnecessary if condidition
try {
if (((BitmapDrawable)master_frame.getDrawable()).getBitmap()!=null) {
((BitmapDrawable)master_frame.getDrawable()).getBitmap().recycle();
}
master_frame.setImageBitmap(master_bitmap);
//maybe try here: master_bitmap.recycle();
}
catch(RuntimeException e) {
e.printStackTrace();
}
}
}
catch (IllegalArgumentException e) {
e.printStackTrace();
}
I'm on a problem by taking the selected gallery picture and want to save it first as Base64 String in a XML file (for later use. For example if you exit the app and open it again).
As you can see I get the Image on a InputStream
But first of all the onClick method:
public void onClick(DialogInterface dialog, int which) {
pictureActionIntent = new Intent(Intent.ACTION_GET_CONTENT);
pictureActionIntent.setType("image/*");
startActivityForResult(pictureActionIntent,GALLERY_PICTURE);
}
Now in the onActivityResult method I want to store the image from InputStream to Base64 String.
case GALLERY_PICTURE:
if (resultCode == RESULT_OK && null != data) {
InputStream inputstream = null;
try {
inputstream = getApplicationContext().getContentResolver().openInputStream(data.getData());
Base64InputStream in = new Base64InputStream(inputstream,0);
} catch (IOException e) {
e.printStackTrace();
}
#EDIT
This is what I do after creating the base64 String.
Bitmap bmp = base64EncodeDecode.decodeBase64(Items.get("image"));
Image1.setImageBitmap(bmp);
And this is the decoding Method:
public Bitmap decodeBase64(String input) {
byte[] decodedByte = Base64.decode(input, Base64.DEFAULT);
return BitmapFactory.decodeByteArray(decodedByte, 0, decodedByte.length);
}
I tried to use Base64InputStream but without success.
Can you give me a hint how to get from InputStream to Base64 String?
How many steps it will take doesn't matter.
I hope someone can help me!
Kind Regards!
Write these lines in onActivityResult method
try {
// get uri from Intent
Uri uri = data.getData();
// get bitmap from uri
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
// store bitmap to file
File filename = new File(Environment.getExternalStorageDirectory(), "imageName.jpg");
FileOutputStream out = new FileOutputStream(filename);
bitmap.compress(Bitmap.CompressFormat.JPEG, 60, out);
out.flush();
out.close();
// get base64 string from file
String base64 = getStringImage(filename);
// use base64 for your next step.
} catch (IOException e) {
e.printStackTrace();
}
private String getStringImage(File file){
try {
FileInputStream fin = new FileInputStream(file);
byte[] imageBytes = new byte[(int)file.length()];
fin.read(imageBytes, 0, imageBytes.length);
fin.close();
return Base64.encodeToString(imageBytes, Base64.DEFAULT);
} catch (Exception ex) {
Log.e(tag, Log.getStackTraceString(ex));
toast("Image Size is Too High to upload.");
}
return null;
}
you can use base64 String of image.
Also don't forget to add permissions in AndroidManifest.xml file READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE
EDIT:: Decode base64 to bitmap
byte[] bytes = Base64.decode(base64.getBytes(), Base64.DEFAULT);
ImageView image = (ImageView) this.findViewById(R.id.ImageView);
image.setImageBitmap(
BitmapFactory.decodeByteArray(bytes, 0, bytes.length)
);
Hope it'll work.
This should work:
public static byte[] getBytes(Bitmap bitmap) {
try{
ByteArrayOutputStream stream = new ByteArrayOutputStream();
stream.flush();
//bitmap.compress(CompressFormat.PNG, 98, stream);
bitmap.compress(CompressFormat.JPEG, 98, stream);
//bitmap.compress(Bitmap.CompressFormat.JPEG, 90, stream);
return stream.toByteArray();
} catch (Exception e){
return new byte[0];
}
}
public static String getString(Bitmap bitmap){
byte [] ba = getBytes(bitmap);
String ba1= android.util.Base64.encodeToString(ba, android.util.Base64.DEFAULT);
return ba1;
}
Got this code from something I use in an application, stripped it down to the most basic as far as i know.
If you are selecting image from Gallery then why you are saving it as Base64 string in xml file , you can reuse that image from gallery .
For this save image url in SharedPreferences and use that url again to show image .
Edit :
If you want to store it locally then you can use SQLite Database to store it , for more detail visit this link .
I am trying to transfer file from a java client to a c# server over UDP. However, when i try to open the transfered file(png picture) on the server side it doesn't succeed open it. Someone please can help me?
The client code:(java)
import java.io.File;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class Program {
public static void main(String [] args)
{
DatagramSocket clientSocket;
try {
clientSocket = new DatagramSocket();
InetAddress IPAddress = InetAddress.getByName("192.168.1.15");
File myFile = new File ("D:/Users/user-pc/Downloads/phone.png");
byte [] data = new byte[(int)myFile.length()];
DatagramPacket sendPacket = new DatagramPacket(data, data.length, IPAddress, 3109);
clientSocket.send(sendPacket);
clientSocket.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
The server code:(c#)
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
byte[] data;
IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 3109);
UdpClient newsock = new UdpClient(ipep);
IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
data = newsock.Receive(ref sender);
File.WriteAllBytes(#"d:\pics\pic.png", data);
}
}
}
byte [] data = new byte[(int)myFile.length()];
That is your problem, you just initialize a new byte array with the length of myFile. (not the actual data)
Here you can see how to convert your File to an actual Byte[]
(Files.toByteArray(File file))
First
Before sending the picture, Decode it to a base64 string .
A helper method here for encoding
public string ImageToBase64(Image image, System.Drawing.Imaging.ImageFormat format)
{
using (MemoryStream stream = new MemoryStream())
{
// Convert Image to byte[]
image.Save(stream , format);
byte[] imageBytes = ms.ToArray();
// Convert byte[] to Base64 String
string base64String = Convert.ToBase64String(imageBytes);
return base64String;
}
}
Encode it into byte array and send it
byte[] data = Encoding.ASCII.GetBytes(returnedStringFromEncoder);
Second :
From the reciever side : convert the bytes array into string back
string data = Encoding.ASCII.GetString(recievedByteArray);
Finally
Convert it into a picture back
public Image Base64ToImage(string base64String)
{
// Convert Base64 String to byte[]
byte[] imageBytes = Convert.FromBase64String(base64String);
MemoryStream stream = new MemoryStream(imageBytes, 0,
imageBytes.Length);
// Convert byte[] to Image
stream.Write(imageBytes, 0, imageBytes.Length);
Image image = Image.FromStream(stream, true);
return image;
}