Android Question Better photo compression

red30

Well-Known Member
Licensed User
Longtime User
I need to reduce the space occupied by the photo. Ideally, the photo should weigh less than 1.5Mb. For this I use the code:
B4X:
Dim Out As OutputStream
Dim FileSize=100 As Int
Bitmap = xui.LoadBitmapResize(File.DirInternal,"FileName.jpg",1280dip,1280dip,True)
Do While File.Size(File.DirInternal,"FileName.jpg")>1500000 And FileSize<>50
    Out = File.OpenOutput(File.DirInternal,"FileName.jpg",False)
    Bitmap.WriteToStream(Out, FileSize, "JPEG")
    Out.Close
    FileSize=FileSize-10
Loop
I have already encountered the problem that if sometimes I reduce the “quality” parameter to less than 50, then large distortions already appear in the photo, so in the condition I used to reduce the quality until the photo weighs more than 1.5Mb and the quality is not equal to 50. But even now I sometimes encounter large photo defects during compression.
Is there a better photo compression algorithm?
 
Last edited:

Quandalle

Member
Licensed User
When the quality becomes low (<50), you can take another approach which is to resize the image to a smaller size while keeping a good JPEG quality. When in use it will be enough to enlarge.

Alternatively you can use the WEBP format which has a compression of about 15% better than JPEG at the same quality. This format is supported natively in Android.

https://developer.android.com/reference/android/graphics/Bitmap.CompressFormat
 
Upvote 0

Pendrush

Well-Known Member
Licensed User
Longtime User
Also you can try this library for WebP
 
Upvote 0

agraham

Expert
Licensed User
Longtime User
Your code above seems invalid as it seems to have "&" instead of "," characters. Android supports WebP from API 14 and as B4A converts strings to enums you could try

Bitmap.WriteToStream(Out, FileSize, "WEBP")
This writes a lossles WebP image if Filesize is 100 or a lossy one if less than 100


Or for API 30 and above explicitly specify the lossy format

Bitmap.WriteToStream(Out, FileSize, "WEBP_LOSSY")
 
Upvote 0

red30

Well-Known Member
Licensed User
Longtime User
Your code above seems invalid as it seems to have "&" instead of "," characters. Android supports WebP from API 14 and as B4A converts strings to enums you could try
Yes, I was wrong. It was just an example. I removed the full path to the file as it is too long and useless for the example. Now everything is corrected.
Bitmap.WriteToStream(Out, FileSize, "WEBP")
This writes a lossles WebP image if Filesize is 100 or a lossy one if less than 100


Or for API 30 and above explicitly specify the lossy format

Bitmap.WriteToStream(Out, FileSize, "WEBP_LOSSY")
I didn't quite understand the difference. For API 30 and out, if I want to set quality <100, should I explicitly set WEBP_LOSSY?
 
Last edited:
Upvote 0

agraham

Expert
Licensed User
Longtime User
For API 30 and out, if I want to set quality <100, should I explicitly set WEBP_LOSSY?
Prior to API 30 there was the single enum WEBP and lossy or lossless was implied by the compression factor. API 30 defined WEBP_LOSSY and WEBP_LOSSLESS to explicitly specify the algorithm. Use of WEBP is deprecated but still available and is what I would use to keep things simple.
 
Last edited:
Upvote 0

red30

Well-Known Member
Licensed User
Longtime User
Prior to API 30 there was the single enum WEBP and lossy or lossless was implied by the compression factor. API 30 defined WEBP_LOSSY and WEBP_LOSSLES to explicitly specify the algorithm. Use of WEBP is deprecated but still available and is what I would use to keep things simple.
That is, you propose to try the same thing that I did, only change the format from "JPEG" to "WEBP"?

I also wonder how things are with the WEBP format in ios?
 
Upvote 0

agraham

Expert
Licensed User
Longtime User
I've played with this and it does work well to save images that are smaller than jpgs and with better quality for the same specified compression factor. Also the Bitmap Initialize methods work to load WebP images so it seems that WebP images are entirely usable if required.
 
Upvote 0
Top