Android Question How to click a button to select an image and determine if the image size is greater than 600KB......

bskotu555

Member
How to click a button to select an image and determine if the image size is greater than 600KB. If it is, compress it. If not, load it directly into the ImageView1 control.Here is my current code:
B4A:
Private Sub Button1_Click
    CC.Show("image/*", "Choose image")
    'CC.Show("audio/*", "Choose audio file")
End Sub

Sub CC_Result (Success As Boolean, Dir As String, FileName As String)
    If Success = True Then
        Dim TargetSize As Int =600 * 1024
        Dim FileSize As Long = File.Size(Dir, FileName)
        If  FileSize > TargetSize  Then
            ResizeImageBasedOnMaxFileSize(xui.LoadBitmap(Dir, FileName), TargetSize, xui.DefaultFolder, FileName)
            ImageView1.Bitmap = LoadBitmap(xui.DefaultFolder,FileName)
        Else
            ImageView1.Bitmap = LoadBitmap(Dir, FileName)
        End If
    Else
        ToastMessageShow("No Success :(",True)
    End If
End Sub

Private Sub ResizeImageBasedOnMaxFileSize (Img As B4XBitmap, MaxSize As Long, OutputFolder As String, OutputFile As String)'图片压缩算法
    Dim Quality As Int = 100
    Dim Size As Long = MaxSize + 1
    Do While Size > MaxSize And Quality >= 10
        Dim out As OutputStream = File.OpenOutput(OutputFolder, OutputFile, False)
        Img.WriteToStream(out, Quality, "JPEG")
        out.Close
        Size = File.Size(OutputFolder, OutputFile)
        Log($"Quality: ${Quality}%, Size: $1.0{Size / 1024}kb"$)
        Quality = Quality - 5
    Loop
End Sub
 

emexes

Expert
Licensed User
Upvote 0

bskotu555

Member
““
Are you reducing images to ≤ 600 kB ( ≤ 800 kB after Base64 encoding) because of the 2 MB Android Sqlite cursor limit?

You are guaranteed a failure if you have an image that is 2M or more. You are very likely to get a failure or issues if an image is say greater than 0.5M.

Also, why not just store the images (JPEG?) as BLOBs in the database+
(instead of encoding them Base64 and storing them as text that is 33% larger than the underlying binary data) (assuming no compression)
”why not just store the images (JPEG?) as BLOBs in the database“,I haven't heard of this method before. Please advise me, master!
 
Upvote 0

MicroDrie

Well-Known Member
Licensed User
Longtime User
Hey guys, this can't get any crazier 😄. Erel advises in post 5 and post 8 to Use XUI.LoadBitmapResize instead and we do nothing with it :eek:🤭? At the bottom of the last post on the first page is staterd on my screen the forum question [B4X] Reduce an image file to a specific size - for example, <500KB to upload to the Forum. Hey guys you are not going to try to tell me that changing from 500,000 to 600,000 bytes in the code example is difficult 😭😂🤣.

Rather than "better well copied than poorly conceived", it seems more like we are reinventing the wheel 🙈🙈🙈🤣🤣🤣🤣
 
Upvote 0

Lucas Siqueira

Active Member
Licensed User
Longtime User
My current approach is to transcode images using base64 and store them in a database, but the database size may become very large in the later stage. This approach may not be very good, and I need to change my thinking: can the images be stored in a disk on the cloud server? I have checked and it seems that FTP technology is available, but I am not sure if B4A supports it
for FTP use:


 
Upvote 0

bskotu555

Member
I appreciate that if what you have is already working, then it might not be worth following up, but if it is, then maybe:

https://www.b4x.com/b4j/help/jsql.html#resultset_getblob

View attachment 161273
B4A:
Sub Class_Globals
    Dim ar() As Byte
End Sub

Private Sub Button1_Click
    Dim CC As ContentChooser
    CC.Initialize("cc")
    CC.Show("image/*", "Choose image")
    Wait For CC_Result (Success As Boolean, Dir As String, FileName As String)
    If Success Then
        ImageView1.Bitmap = LoadBitmap(Dir, FileName)
        ar=ReadFile(Dir,FileName)   
    End If
End Sub

Private Sub Button2_Click'上传数据库
    If EditText1.Text<>"" Then
        StartService(Starter)
        Dim sqlstr As String
        Dim myBitmap As B4XBitmap = ImageView1.Bitmap'获取加载的图片
'        Dim nc As String= Base64EncodeDecodeImage.Base64ImageToString2(myBitmap)'图片转Base64方法
        Dim cx As String = phone.GetSettings ("android_id")'获取设备ID
        Dim tx As String=EditText1.Text'价格
        Dim tt As String=DateTime.Date(DateTime.Now)'时间
        
        sqlstr = "insert into 记录表(设备ID,账单图片,账单价格,记录日期) values('" & cx & "','" & nc & "','" & tx & "','" & tt & "')"
        
        Starter.Mysql_Jdbc.ExecNonQuery(sqlstr)
        EditText1.Text=""
        MsgboxAsync("入账成功!","提示")
    End If
End Sub
How do I write the statement 'sqlstr' if I store the binary array 'ar' into a MySQL database?
 
Upvote 0

emexes

Expert
Licensed User
If I convert the image to binary, set the longblob field in the database, and then upload it, how do I write the SQL statement?

For a database containing images eg here the picture column is type BLOB:

B4X:
SQL1.Initialize(File.DirInternal, "cakes.db", True)
SQL1.ExecNonQuery("CREATE TABLE IF NOT EXISTS cakes (age INTEGER, url TEXT, picture BLOB)")

then to store a downloaded image to the database:

B4X:
Dim job As HttpJob
job.Initialize("", Me)
job.Download(CakePictureURL)

Wait For (job) JobDone(job As HttpJob)
If job.Success Then
    Dim out As OutputStream
    out.InitializeToBytesArray(100)
    File.Copy2(job.GetInputStream, out)
    out.Close

    Dim CakePictureBlob() As Byte = out.ToBytesArray

    SQL1.ExecNonQuery2("INSERT INTO cakes VALUES(?, ?, ?)", Array As Object(NumCandles, CakePictureURL, CakePictureBlob))
    Log("Added" & TAB & CakePictureBlob.Length & TAB & CakePictureURL)

and to retrieve the stored image from the database:

B4X:
Private Sub SeekBar1_ValueChanged (Value As Int, UserChanged As Boolean)
    Dim Cursor1 As Cursor = SQL1.ExecQuery("SELECT * FROM cakes")
    If Cursor1.RowCount > 0 Then
        If Value < Cursor1.RowCount Then
            Cursor1.Position = Value
        Else
            Cursor1.Position = Cursor1.RowCount - 1
        End If
     
        Dim CakePicture() As Byte = Cursor1.GetBlob("picture")

        Dim In As InputStream
        In.InitializeFromBytesArray(CakePicture, 0, CakePicture.Length)
        Dim bmp As Bitmap
        bmp.Initialize2(In)
        In.Close

        ImageView1.Bitmap = bmp
    End If
End Sub

Full project attached. Stripped out from a similar images-stored-in-database project that I did a few years back, before I had a grip on writing ResumableSubs. I apologise in advance for the large Sub that finds and downloads and adds images to the database.

Click the button to add new images. Does a Bing image search for relevant pictures, pulls out the JPEG and JPG image URLs, does a HTTP header check to check the image is a reasonable size 5-70 kB, and if so, downloads the picture and adds it to the database (as a BLOB aka Binary Large OBject aka a bunch of raw bytes).

First time you run the app, the database is empty, nothing gets displayed until the first time you click the button. Bear in mind that most of the candidate images are too large, so it might be 10-20 seconds before it chances upon an image that fits the size criteria.
 

Attachments

  • TestBlob.zip
    10.8 KB · Views: 21
Last edited:
Upvote 0
Top