Bitmap - compare contact picture with picture on sd card - android

I want to check, if the current user picture of a contact is the same as the one on the sd card...
I set the user picture like following:
byte[] photo = ImageFunctions.convertImageToByteArray(bitmap);
ContentValues values = new ContentValues();
....
values.put(ContactsContract.CommonDataKinds.Photo.PHOTO, photo);
...
And I read the image like following:
InputStream inputStream = ContactsContract.Contacts.openContactPhotoInputStream(
contentResolver,
ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, mId),
fullsize);
if (inputStream != null)
return BitmapFactory.decodeStream(inputStream);
And my convert function is following:
public static byte[] convertImageToByteArray(Bitmap bitmap)
{
ByteArrayOutputStream streamy = new ByteArrayOutputStream();
bitmap.compress(CompressFormat.JPEG, 100, streamy);
return streamy.toByteArray();
}
And I use a md5 hash on the byte array of the bitmap to find changes... Actually, the images are not exactly the same.
What can I do, so that I compare the hash codes? It seems, like compression or whatever is not exactly the same, so the md5 hash check fails...

Related

Why is my BitmapFactory.decodeByteArray returning null?

I am trying to convert an image stored in Database in Base64 format, to a Bitmap to be used in an Imageview.
So, I store it in SQLite this way:
Bitmap imageBitmap = (Bitmap) extras.get("data");
ByteArrayOutputStream stream = new ByteArrayOutputStream();
Bitmap fotoGrande=(Bitmap) extras.get("data");
imageBitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
//I am adding some data to EXIF here, add to an static ArrayList<Bitmap> in other class and I store it this way:
int bytes=listaFotos.get(i).getFoto().getByteCount();
ByteBuffer buffer = ByteBuffer.allocate(bytes);
listaFotos.get(i).getFoto().copyPixelsToBuffer(buffer);
values.put("foto", Base64.encodeToString(buffer.array(), Base64.DEFAULT));
Later, i need to get that image to fit it in an ImageView:
String foto = csr2.getString(0);//csr2 is a cursor
byte[] arrayFoto = Base64.decode(foto, Base64.DEFAULT);//This is not null
Bitmap fotoBitmap = BitmapFactory.decodeByteArray(arrayFoto, 0, arrayFoto.length);//This is null
I know there are tons of questions about this. I searched, but no answer fix my problem.
Why is my BitmapFactory.decodeByteArray returning null? What I am doing wrong? Any help?
Thank you.
Turned out to be a database issue. SQLite gives you a cursor of 1MB MAX size. I was getting the bytes from database, with a 1MB cursor, the pic was not sent properly.
To fix it, I stored the path to the photo in database instead of the bytes.
firstly image is convert in Bitmap to String like this
ByteArrayOutputStream stream = new ByteArrayOutputStream();
camera.compress(Bitmap.CompressFormat.JPEG, 100, stream);
byte imageInByte[] = stream.toByteArray();
String encodedImage = Base64.encodeToString(imageInByte, Base64.DEFAULT);
where camera is a Bitmap.
and store the String encodedImage in database
And getImage string like this
byte[] b = Base64.decode(encodedImage , Base64.DEFAULT);
Bitmap bitmap = BitmapFactory.decodeByteArray(b, 0, b.length);

Image Uri to File

I've got an Image Uri, retrieved using the following:
public Uri getImageUri(Context inContext, Bitmap inImage) {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
String path = Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null);
return Uri.parse(path);
}
This works just amazing for Intents that require an Image URI, etc (so I know for sure the URI is valid).
But now I want to save this Image URI to a file on the SDCARD. This is more difficult because the URI does not really point at a file on the SDCARD or the app.
Will I have to create a bitmap from the URI first, and then save the Bitmap on the SDCARD or is there a quicker way (preferable one that does not require the conversion to a bitmap first).
(I've had a look at this answer, but it returns file not found - https://stackoverflow.com/a/13133974/1683141)
The problem is that the Uri you've been given by Images.Media.insertImage() isn't to an image file, per se. It is to a database entry in the Gallery. So what you need to do is read the data from that Uri and write it out to a new file in the external storage using this answer https://stackoverflow.com/a/8664605/772095
This doesn't require creating a Bitmap, just duplicating the data linked to the Uri into a new file.
You can get the data using an InputStream using code like:
InputStream in = getContentResolver().openInputStream(imgUri);
Update
This is completely untested code, but you should be able to do something like this:
Uri imgUri = getImageUri(this, bitmap); // I'll assume this is a Context and bitmap is a Bitmap
final int chunkSize = 1024; // We'll read in one kB at a time
byte[] imageData = new byte[chunkSize];
try {
InputStream in = getContentResolver().openInputStream(imgUri);
OutputStream out = new FileOutputStream(file); // I'm assuming you already have the File object for where you're writing to
int bytesRead;
while ((bytesRead = in.read(imageData)) > 0) {
out.write(Arrays.copyOfRange(imageData, 0, Math.max(0, bytesRead)));
}
} catch (Exception ex) {
Log.e("Something went wrong.", ex);
} finally {
in.close();
out.close();
}

How to save image to sqlite database selected from gallery or captured from camera to sqlite database

I want to store image to sqlite database using blob selected from gallery or captured from camera and get back thease images from database to display in listview or gridview.
It's possible to store image and retrieve image from sqlite database.
code to store it
// Convert your bitmap to byte array
ByteArrayOutputStream out = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
byte[] bytes = out.toByteArray();
ContentValues cv = new ContentValues();
cv.put("IMAGE", bytes);
code to retrieve it
// Use Cursor to retrieve the image
byte[] bytes = cursor.getBlob(column_index);
ByteArrayInputStream input = new ByteArrayInputStream(bytes);
Bitmap bit = BitmapFactory.decodeStream(input);

How to display image from blob data in android sqlite?

I have been trying to store image form android sdcard to the sqlite database. And it worked fine. The image is getting stored into the database as blob. This is the rough code I have been using for that.
Bitmap bitmap = BitmapFactory.decodeFile(filePath);
imgView.setImageBitmap(bitmap);
int size = bitmap.getWidth() * bitmap.getHeight();
ByteArrayOutputStream out = new ByteArrayOutputStream(size);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
try {
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();}
byte[] x = out.toByteArray();
In the database side, the code is like this
ContentValues values = new ContentValues();
byte[] bytes = null;
bytes = img_bytes.getBytes();
values.put("IMAGE", bytes);
And for displaying I have used the code as below.
ImageView image = new ImageView(this);
byte[] img_bytes = result.get("IMAGE").getBytes();
Bitmap bMap = BitmapFactory.decodeByteArray(img_bytes, 0, img_bytes.length);
image.setImageBitmap(bMap);
When I printed the string value of the byate array, it was getting like [B#44da2db0. But the byte array is not getting displayed into image.
Somebody please help me with this.
Thanks
I have found a solution. Thanks to all.
I have used base64 encoding method.
ie; For displaying the image, I have been using a hash map to get the result first of all from the database table.
So before saving into the map, I have encoded the bytes to string using base 64 method.
Then On the Activity side for displaying the image, I have decoded back the string using base 64 again and then converted to bytes and the image got displayed.

How to attach EXIF metadata to a serialized Bitmap in Android?

In Android, when decoding a Bitmap from a photo on the phone, the EXIF data in the original gets lost. I am sending this Bitmap to my server via a socket and would like to re-attach the missing EXIF data to the data being sent.
I have some code that loads a Bitmap object from the MediaStore and compresses it to a byte array in preparation to send it over a socket:
Bitmap bitmap = ...
ByteArrayOutputStream stream = new ByteArrayOutputStream(bitmap);
bitmap.compress(CompressFormat.JPEG, 70, stream);
byte[] input = stream.toByteArray();
I want to use the ExifInterface to get at the EXIF metadata in the original jpeg on the SD card and somehow add that to the outgoing byte array in a way that I'd be able to extract a jpeg with all the correct EXIF on the server side (hopefully without doing this on the server). So far, I managed to use the ExifInterface to read all EXIF data:
String path = ... //bitmap file path
ExifInterface exif = new ExifInterface(path);
... = exif.getAttribute(...)
EDIT: Optimally, I'd like to find a solution that uses no libraries. If I could just get the indices of the byte array of the original jpeg that contain the EXIF and prepend/append these bytes to the byte array produced by bitmap.compress(...) that would be best.
Thanks to #Nick Campion and Sanselan.
Working code:
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bitmap.compress(CompressFormat.JPEG, 100, bos); //Bitmap object is your image
byte[] data = bos.toByteArray();
TiffOutputSet outputSet = null;
IImageMetadata metadata = Sanselan.getMetadata(new File(filepath)); // filepath is the path to your image file stored in SD card (which contains exif info)
JpegImageMetadata jpegMetadata = (JpegImageMetadata) metadata;
if (null != jpegMetadata)
{
TiffImageMetadata exif = jpegMetadata.getExif();
if (null != exif)
{
outputSet = exif.getOutputSet();
}
}
if (null != outputSet)
{
bos.flush();
bos.close();
bos = new ByteArrayOutputStream();
ExifRewriter ER = new ExifRewriter();
ER.updateExifMetadataLossless(data, bos, outputSet);
data = bos.toByteArray(); //Update you Byte array, Now it contains exif information!
}

Categories

Resources