Image comparator returns false - android

So, I'm using a file sharing app on Android. It creates a duplicate copy which is uploaded to it's server.
PROBLEM
The following code works for a duplicate copy I manually create. That is, I long press and copy the file into the same directory with a File Manager. Then my function returns true. When it compares the duplicate image due to the app and the original image, I get false.
MD5-checksums are different so that is out of the options.
CODE
public boolean equals(Bitmap bitmap1, Bitmap bitmap2) {
ByteBuffer buffer1 = ByteBuffer.allocate(bitmap1.getHeight()
* bitmap1.getRowBytes());
bitmap1.copyPixelsToBuffer(buffer1);
ByteBuffer buffer2 = ByteBuffer.allocate(bitmap2.getHeight()
* bitmap2.getRowBytes());
bitmap2.copyPixelsToBuffer(buffer2);
return Arrays.equals(buffer1.array(), buffer2.array());
}
Here are the images :
Original image -
Duplicate image created by the app -
My code currently returns false while comparing these two images.
How do I get the code to return true?

Your problem is due to artefacts created by JPEG compression, if you can always keep the images in PNG then your problem is most likely solved. If you can't do that, then you need a better algorithm to compare the images. This is exactly the same problem discussed at Comparing image in url to image in filesystem in python
For instance, running the algorithms mentioned in the earlier discussion, we get a similarity of more than 99%. With that similarity value, you can say the images are the same.

Related

best way to compare images for similarity in android

how to compare two images, to know are they similar for 100%?
I was getting path of all images from mediastore, then converted to bitmap and compared using bitmap.sameAs(bitmapToCompare), but it takes to much memory and got outofmemory exepcetion
Now i am trying to use OpenCv library as:
val img1: Mat = Imgcodecs.imread(it)
val img2: Mat = Imgcodecs.imread(it1)
val result = Mat()
Core.compare(img1, img2, result, Core.CMP_EQ)
val ines = Core.countNonZero(result)
if(ines==0){
//similar images
}
but get an error in Core.countNonZero as following:
cv::Exception: OpenCV(4.5.3) /home/quickbirdstudios/opencv/releases/opencv-4.5.3/modules/core/src/count_non_zero.dispatch.cpp:128: error: (-215:Assertion failed) cn == 1 in function 'countNonZero'
so what is best way to compare two images?
First off, let's correct you. Neither your OpenCV snippet not Android can directly compare if two images are "similar". They can compare if they are exactly the same. That's not the same thing. You'd have to decide if its good enough.
Secondly, OpenCV is overkill for this. If the two images are Bitmaps in memory, just loop over the byte arrays of the two files. If they're on disk, just compare the byte by byte data of the two files.
You said you "got the paths of all images, then converted to Bitmap". Yeah, that would take a ton of memory. Instead, if you want to compare all the files, do this:
val map = mutableMapOf()
fileNames.each {
val hash = hash_file(it)
if (map.contains(hash)) {
//In this case, the two file stored in it and map[hash] are the same
}
else {
map[hash] = it
}
}
Here hash_file is any well known hash function. MD5 would work fine.
Now if you actually want similarity- good luck, you're going to need to learn a lot of AI and machine learning to determine that. Or find someone who already has a model for an appropriate training set.

LruCache returning wrong bitmaps for specified key

I am very new to Android development.
I am running into issues getting the correct bitmap from my LruBitmapCache. I use the UUID to generate a unique Id, I don't use a URL because I am generating the bitmap on a canvas. (I'm copying getDrawingCache() from my view to a new bitmap (using copy) then storing the copy into the cache).
For some reason after I store a bitmap, when I access it, it ends up being a bitmap for another id ... this happens sometimes. Any ideas?
I use a currentIndex to track which position I am at in the cachedKeys Array (I want to sequentially save and navigate through the bitamp on a canvas). I think I'm updating the entry in the cache wrong...
A fellow developer assisted. I was doing mDrawingView.restartDrawingCache(); incorrectly and in the wrong order.
It should have been:
<drawing view>.setDrawingCacheEnabled(true);
Bitmap mmap= <drawing view>.getDrawingCache();
Bitmap copy = mmap.copy(mmap.getConfig(), false);
<drawing view>.setDrawingCacheEnabled(false);
Cheers, maybe this will help someone out :)

Get resource ID from URI or Bitmap

Is there anyway I can find resource ID from Bitmap, URI, file path or file name of an image? These images are written by my app. So is there any chance I can find the resource ID?
Basically, I have GIF images stored in my SD Card (which are created by my app). I want to load those images to my viewer. For that, I am using GIF Movie View library. In that file, setMovieResource() expecting an int (resource ID). But I have all other info like bitmap, absolute path.
Resource IDs are automatically generated by Android for files inside the resource folder (/res) only. Out of that folder, there is no such thing called "resource ID".
Some Android components (such as Views) do have ID and can be set manually. However, manually-set ID is not listed inside R.java, the collection of resource IDs generated by Android.
But in your case, generated images don't have ID, so it's impossible to get something that doesn't exist beforehand.
Regarding the library, there is another function to set the image from source without resource ID:
public void setMovie(Movie movie) {
this.mMovie = movie;
requestLayout();
}
Now, looking at the Movie class which is included in Android SDK, there are other functions to decode a source: decodeByteArray() and decodeFile(). decodeByteArray() accepts a byte array, and decodeFile() accepts a file path, which can be used if you have the full path to the file.
While Bitmap can be converted to byte array, I'm not sure whether Bitmap supports multiple layers/animation of a GIF image, so I'll avoid the first approach. Instead, you can try this:
GifMovieView gifMovieView = ... ; // the reference to the view
String filePath = ... ; // the full file path to the GIF image
Movie myMovie = Movie.decodeFile(pathName);
gifMovieView.setMovie(myMovie);
(The above code is not tested yet)

Getting application size in Android

I want to get the application size (in bytes). The way I tried was as follows:
PackageStats ps = new PackageStats(packageInfo.packageName);
int size = ps.codeSize;
This returns 0 every time. (Bascially every value returned is 0 - cacheSize, dataSize etc)
I do not want to use reflection as mentioned here (as its a non documented way)
So is there any way to fetch this information ?
One definition of application size is the size of the apk file in bytes.
You can get that by doing new File() on the ApplicationInfo.sourceDir value for the application, and then doing a File.length() on that file.
Contrary to the sound of the class name, PackageStats.class doesn't access system on your phone and find the size of your app, data, and cache files (wish it did). It is used to pull this information (if available) from a parcel, or to take a package and write this information if provided by the package into a parcel.
Using zmarties approach, new File(), is a workable solution.

Android : Bitmap : From parcel : Out of memorry exception

I am using a bundle to send a bitmap from one application to another.
And i retrieve the bitmap from the bundle for use in a different application.
The specific use of bundle was necessary in this place.
And when i read it out i get a OUT OF MEMORY EXCEPTION.
bitmap = (Bitmap)receivedmsg.getData().getParcelable("myobject");
Any suggestions ?
It means what it says. The image you serialized is too big to be read back into memory in the other app. The fastest fix is what M Mohsin Naeem alludes to: you need to make the image smaller! Do so in the app that sends the image. For example, if that app is reading from a file, you can set it to down-sample the image to a smaller size.
Also consider whether you really need to send the image this way, or whether you could save it to the SD card, and then process it without reading into memory.

Categories

Resources