I'm using BluetoothSPP Android Library. I have problems for send and receive data byte[]
User 1 takes a photo from camera, get it and send to other user.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 0) {
if (resultCode == RESULT_OK) {
Bundle bundle = data.getExtras();
Bitmap bitmap = (Bitmap) bundle.get("data");
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
byte[] bitmapByte = outputStream.toByteArray();
bluetoothSPP.send(bitmapByte, true); **//Send the Bitmap array**
}
}
User 2 receive the Bitmap byte[].
bluetoothspp.setOnDataReceivedListener(new BluetoothSPP.OnDataReceivedListener() {
public void onDataReceived(byte[] data, String message) {
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
Glide.with(ChatActivity.this).load(bitmap ).asBitmap().into(imgFundo); //Use Glide for show Bitmap
}
});
But I always get an error and Glide can not display the image.
I did a debug and the data comes in several parts, like an array of bytes.
- How can I build a Bitmap from data received?
Thanks
Related
I am very close to having this work. I get a picture from the camera and store it in my SQLite database. However when I store it, I get this error. The byte array for the image is null when stored. Why? How can I fix it?
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.psa.stepbystep, PID: 16363
java.lang.NullPointerException: Attempt to get length of null array
at com.example.psa.stepbystep.Walk.writeToParcel(Walk.java:161)
at android.os.Parcel.writeParcelable(Parcel.java:1730)
at android.os.Parcel.writeValue(Parcel.java:1636)
at android.os.Parcel.writeArrayMapInternal(Parcel.java:777)
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1506)
Walk Activity contains Parcel
public Walk(Parcel in) {
this._photo = new byte[in.readInt()];
in.readByteArray(_photo);
}
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(_photo.length);
dest.writeByteArray(_photo);
}
WalkPhoto has this to convert
//Convert from bitmap to byte array
public static byte[] getBytes(Bitmap bitmap) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 0, stream);
return stream.toByteArray();
}
//Convert from byte array to bitmap
public static Bitmap getImage(byte[] image) {
return BitmapFactory.decodeByteArray(image, 0, image.length);
}
WalkPhoto also has this to store the image in the database
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
Bundle extras = data.getExtras();
Bitmap imageBitmap = (Bitmap) extras.get("data");
ImageView imageview = findViewById(R.id.imageView);
imageview.setImageBitmap(imageBitmap);
//Bitmap to bytes for database
byte[] photo = getBytes(imageBitmap);
DatabaseHandler mydb = new DatabaseHandler(getApplicationContext());
Walk walk = new Walk(photo);
mydb.addWalk(walk);
}
You can use "blob" to store image as mention in this post: https://stackoverflow.com/a/9357943/5455940
In above post "insertStatement_logo" is instance of SQLiteStatement class.
SQLiteStatement is subclass of SQLiteProgram class.
See links for reference.
https://developer.android.com/reference/android/database/sqlite/SQLiteStatement.html
https://developer.android.com/reference/android/database/sqlite/SQLiteProgram.html
I have a simple ImageView that when I click on it the camera appears and requests a photo, you take the photo and that ImageView turns into the photo, stuff like this:
Uri pictureUri;
ImageViewer pic = findViewById(...);
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAMERA_PIC_REQUEST) {
try {
Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
String path=String.valueOf(data.getData());
pictureUri = Uri.fromFile(new File(path));
pic.setImageBitmap(thumbnail);
After the camera request the picture is loaded into the Imageviewer but and then I try to upload it to Firebase using:
StorageMetadata metadata = new StorageMetadata.Builder()
.setContentType(animal.getPictureID()+"/jpeg")
.build();
mStorageRef.child(animal.getPictureID()).putFile(pictureUri,metadata);
Where animal.getPictureID it's simply an ID given before. Now the issue here is that at the putFile() it keeps returning FileNotFoundException.
Also while we're at it if you know why the image in Imageviewer is in such low quality it would also be ncie but the main issue is really the Firebase storage.
You can get Bitmap from request by using:
InputStream stream = getContentResolver().openInputStream(data.getData());
Bitmap bitmap = BitmapFactory.decodeStream(stream);
To store it to Firebase storage:
String path = "images/"+imgName;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// this will compress an image that the uplaod and download would be faster
bitmap.compress(Bitmap.CompressFormat.JPEG, 50, baos);
byte[] data = baos.toByteArray();
FirebaseStorage storage = FirebaseStorage.getInstance();
StorageReference storageReference = storage.getReference();
StorageReference reference = storageReference.child(path);
UploadTask uploadTask = reference.putBytes(data);
uploadTask.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Log.i(TAG, "Image was saved");
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.e(TAG, "Image wasn't saved. Exception: "+e.getMessage());
}
});
You can use the Base64 Android class:
String encodedImage = Base64.encodeToString(byteArrayImage, Base64.DEFAULT);
You'll have to convert your image into a byte array though. Here's an example:
Bitmap bm = BitmapFactory.decodeFile("/path/to/image.jpg");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.JPEG, 100, baos); //bm is the bitmap object
byte[] b = baos.toByteArray();
and decode the image when needed back
So I'm making a list app for wine where you can put in details and an image about wines that you enter and put the data into an SQLite database on the phone.
I just worked out getting the image into the database but it's very low quality, even though I have the quality integer set to 95 (out of 100).
Can anyone give tips on how to do this in a better way?
Here is the relevant info from the AddActivity:
btnAddPicture.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, 1888);
}
});
//this method happens after taking the image
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){
if (requestCode == 1888 && resultCode == RESULT_OK){
toastMessage("Image has been taken successfully");
Bundle extras = data.getExtras();
Bitmap imageBitmap = (Bitmap) extras.get("data");
ByteArrayOutputStream stream = new ByteArrayOutputStream();
imageBitmap.compress(Bitmap.CompressFormat.JPEG, 95, stream);
imageInByte = stream.toByteArray();
}
}
I then put that imageInByte variable into the database.
The reason that the image is such low quality is that it is actually getting the thumbnail version of the picture.
Bundle extras = data.getExtras();
Bitmap imageBitmap = (Bitmap) extras.get("data");
This doesn't retrieve the full image. If you want the full image, you need to use the EXTRA_OUTPUT extra to save the full image. Then, you can put the file path into the database to retrieve the full sized image.
For documentation on ACTION_IMAGE_CAPTURE:
https://developer.android.com/reference/android/provider/MediaStore.html#ACTION_IMAGE_CAPTURE
Hope this helps anyone else!
In my app i need to pick image from gallery to my ImageView. If I pick simple image, for example, downloaded from the Internet, it works fine. But if i pick photo made on my phone i get W/OpenGLRenderer: Bitmap too large to be uploaded into a texture (4160x3120, max=4096x4096)
Using Glide to load the photo gives this
Caused by: java.lang.IllegalArgumentException: Unknown type class android.graphics.Bitmap. You must provide a Model of a type for which there is a registered ModelLoader, if you are using a custom model, you must first call Glide#register with a ModelLoaderFactory for your custom model class
This is my code which picks up an image and creates a bitmap out of it.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// When an Image is picked
if (requestCode == SELECT_PHOTO && resultCode == RESULT_OK
&& null != data) {
Uri imageUri = data.getData();
InputStream inputStream;
try {
inputStream = getContentResolver().openInputStream(imageUri);
Bitmap image = BitmapFactory.decodeStream(inputStream);
commentImage = (ImageView) findViewById(R.id.comment_image);
//Glide.with(this).load(image).asBitmap().override(4095, 4095).into(commentImage);
commentImage.setImageBitmap(image);
//commentImage.setImageBitmap(Bitmap.createScaledBitmap(image, 4095, 2048, false));
Toast.makeText(this, "SUCCESS", Toast.LENGTH_LONG).show();
} catch (FileNotFoundException e) {
e.printStackTrace();
// show a message to the user indictating that the image is unavailable.
Toast.makeText(this, "Unable to open image", Toast.LENGTH_LONG).show();
}
} else {
Toast.makeText(this, "You haven't picked Image",
Toast.LENGTH_LONG).show();
}
}
How can I scale an Image in case if it is too big?
You can use the following to compress the bitmap, here bitmapImage is your bitmap object. :
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bitmapImage.compress(Bitmap.CompressFormat.JPEG, 90, byteArrayOutputStream); //90 refers to 90% quality, or 10% compression
byte[] data = byteArrayOutputStream.toByteArray();
Bitmap compressedBitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
I would like to load image from gallery and then convert it into base64.
This does not sound so difficult. So i dod it this way:
first of all open gallery and choose picture:
picteureBtn.setOnClickListener(new View.OnClickListener() {
private Uri imageUri;
public void onClick(View view) {
Intent i = new Intent(
Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, RESULT_LOAD_IMAGE);
}
});
second onActivityResult:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && 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]);
picturePath = cursor.getString(columnIndex);
cursor.close();
}
}
and for the end way i want to decode my image which is at picutrePath
String b64;
StringEntity se;
String entityContents="";
if (!picturePath.equals("")){
Bitmap bm = BitmapFactory.decodeFile(picturePath);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] b = baos.toByteArray();
b64=Base64.encodeToString(b, Base64.DEFAULT);
}
Unfortunatly I get :
06-24 16:38:14.296: E/AndroidRuntime(3538): FATAL EXCEPTION: main
06-24 16:38:14.296: E/AndroidRuntime(3538): java.lang.OutOfMemoryError
06-24 16:38:14.296: E/AndroidRuntime(3538): at java.io.ByteArrayOutputStream.toByteArray(ByteArrayOutputStream.java:122)
Can anyone point me where I am doing mistake?
I'd suggest to change
Bitmap bm = BitmapFactory.decodeFile(picturePath);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.JPEG, 100, baos);
//added lines
bm.recycle();
bm = null;
//added lines
byte[] b = baos.toByteArray();
b64=Base64.encodeToString(b, Base64.DEFAULT);
That way, you're not loading the Bitmap twice into your app's memory.
There are a lot of articles talking about this, basically you will need to calculate the dimensions before trying to decode it into a Bitmap have a look at the BitmapFactory class. I have an alternative solution for you, since you are picking a picture from the gallery, you can can get the Bitmap in activityForResult, like this:
Bitmap image = (Bitmap) data.getExtras().get("data");
and you can start your Intent for getting the images like:
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(intent, RESULT_LOAD_IMAGE);