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?
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.
Convert/Compress Image between different formats WebP, JPG, PNG. ConvertImage Author: Pendrush Version: 1.00 ConvertImage Events: OnComplete OnError (Error As String) Fields: TO_JPEG As android.graphics.Bitmap.CompressFormat Compress to the JPEG format TO_PNG As...
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
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.
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.
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.
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.