Android Question Image to/from CVS File

Guenter Becker

Active Member
Licensed User
Hello,
I have 3 table columns named "ColA", ColB" and "ColC" where ColC is type BLOB and I like to store and read images in/from it.
For a solution I like to export these table columns to a CVS File or import the CVS file values to the table columns.

I know how to convert the image to a byte array and back and I know also that I have to convert the byte array to a string and back for import.

This is where I need help with a b4a snipped .
  1. How to convert the byte array to a string(variable)?
  2. How to convert the string(variable) to a byte array?
Has anyone an Idea of a solution?
 

Jeffrey Cameron

Well-Known Member
Licensed User
Longtime User
You will need the StringUtils library to encode/decode your byte array into/from a base-64 string for storage. You can use the OutputStream object (from the RandomAccess library, I think) to save your bitmap into a byte array that you can pass to the encode function, and the Bitmap object itself has an initialize method that can take a byte array.

Search this forum for "ImageToBytes" and "BytesToImage" and I think you'll find example methods in several posts.

Having said that, I always strongly discourage people from storing complete images (i.e. not small thumbnails) directly in databases. The performance hit to the database is substantial and there is usually no storage savings over an organized images folder holding the images directly.
 
Upvote 0

Guenter Becker

Active Member
Licensed User
Thank you Guys I followed your proposals. What I was really missing was the tip to encode64.
Found several solutions in the Forum.
 
Upvote 0

MicroDrie

Well-Known Member
Licensed User
Maybe you can use of the following routines as a startingpoint
Image routines:
#Region ImageRoutines

Public Sub BytesToFile (Dir As String, FileName As String, Data() As Byte)
    Dim out As OutputStream = File.OpenOutput(Dir, FileName, False)
    out.WriteBytes(Data, 0, Data.Length)
    out.Close
End Sub

Public Sub FileToBytes (Dir As String, FileName As String) As Byte()
    Return Bit.InputStreamToBytes(File.OpenInput(Dir, FileName))
End Sub

' Converts image to JPEG byte array. Ability to resize and adjust JPEG quality.
' Negative width and height values = %, such that -50 = 50% and -200 = 200%
' Positive width and height values = pixel dimensions
' If one value (either width or height) are 0, then the other value is proportionally
'  calculated from the first.
' If both width and height are 0 or -100, no resizing takes place
' If quality = -1, use default quality of 75
' Will return a zero length byte array if something is wrong with the parameters
Public Sub XUIImageToJPEGByteArray(aImage As Object, width As Int, height As Int, quality As Int) As Byte()
    'Sanity check quality
    If (quality < -1 And quality > 100) Then
        Log("Parameter quality not in range (-1..100)")
        Return Array As Byte ()
    End If
    If quality = -1 Then quality = 75

    'Sanity check incoming image
    Try
        Dim image As B4XBitmap = aImage
    Catch
        Log(LastException)
        Return Array As Byte ()
    End Try
  
    'Sanity check incoming image dimensions
    Dim oldWidth As Int = image.Width
    Dim oldHeight As Int = image.Height
    If (oldWidth = 0 And oldHeight = 0 ) Then
        Log("Source image with incorrect dimensions")
        Return Array As Byte ()
    End If

    'See if were resizing the image
    Dim  resize As Boolean = True
    If ((width = 0 And height = 0) Or (width = -100 Or height = -100)) Then resize = False
  
    'Resize if necessary
    If (resize) Then
        Dim newWidth As Int = width
        Dim newHeight As Int = height
        'Calculate new dimensions
        If (newWidth < 0) Then newWidth = -1 * oldWidth * newWidth / 100
        If (newHeight < 0) Then newHeight = -1 * oldHeight * newHeight / 100
        If (newWidth = 0) Then newWidth = oldWidth * newHeight / oldHeight
        If (newHeight = 0 ) Then newHeight = oldHeight * newWidth / oldWidth
        image = image.Resize(newWidth, newHeight, False)
    End If
  
    'Convert image to JPEG byte array
    Dim out As OutputStream
    out.InitializeToBytesArray(0)
    image.WriteToStream(out, quality, "JPEG")
    out.Close
    'Done
    Return out.ToBytesArray
End Sub

#IF B4J
Public Sub WriteBase64Image(img As Image)
    Dim su As StringUtils
    Dim out As OutputStream
    out.InitializeToBytesArray( 0 )
    img.WriteToStream( out )

    Dim encoded As String = su.EncodeBase64( out.ToBytesArray )
    File.WriteString( File.DirApp, "base64Image.txt", encoded ) ' <- creates a textFile
    Log ( encoded ) '<- show the actual encoded text
    out.Close
End Sub
#END IF

#IF B4A
Public Sub WriteBase64Image(Path As String, img As Bitmap, Quality As Int, Format As String)
    Dim su As StringUtils
    Dim out As OutputStream
    out.InitializeToBytesArray( 0 )
    img.WriteToStream(out, Quality, Format )

    Dim encoded As String = su.EncodeBase64( out.ToBytesArray )
    File.WriteString(Path, "base64Image.txt", encoded ) ' <- creates a textFile
    Log ( encoded ) '<- show the actual encoded text
    out.Close
End Sub
#END IF

Public Sub XuiImageToBytes(Image As B4XBitmap) As Byte()
    Dim out As OutputStream
    out.InitializeToBytesArray(0)
    Image.WriteToStream(out, 100, "JPEG")
    out.Close
    Return out.ToBytesArray
End Sub

Public Sub BytesToImage(bytes() As Byte) As B4XBitmap
    Dim In As InputStream
    In.InitializeFromBytesArray(bytes, 0, bytes.Length)
#if B4A or B4i
    Dim bmp As Bitmap
    bmp.Initialize2(In)
#else
    Dim bmp As Image
    bmp.Initialize2(In)
#end if
    Return bmp
End Sub

' Needs JavaObject library
#IF B4J
Public Sub SaveImage(img As Image, out As OutputStream)
#ELSE IF B4A
Public Sub SaveImage(img As Bitmap, out As OutputStream)
#END IF
    Dim jo As JavaObject = Me
    Dim dpi As Float = 96
    jo.RunMethod("saveImage", Array(out,img,  dpi))
    out.Close
End Sub

Sub FitImageToView(bmp As B4XBitmap, ImageView As B4XView)
    Dim scale As Float = 1
    #if B4i
    scale = GetDeviceLayoutValues.NonnormalizedScale
    #End If
    ImageView.SetBitmap(bmp.Resize(ImageView.Width * scale, ImageView.Height * scale, True))
End Sub

Public Sub FillImageToView(bmp As B4XBitmap, ImageView As B4XView)
    Dim bmpRatio As Float = bmp.Width / bmp.Height
    Dim viewRatio As Float = ImageView.Width / ImageView.Height
    If viewRatio > bmpRatio Then
        Dim NewHeight As Int = bmp.Width / viewRatio
        bmp = bmp.Crop(0, bmp.Height / 2 - NewHeight / 2, bmp.Width, NewHeight)
    Else if viewRatio < bmpRatio Then
        Dim NewWidth As Int = bmp.Height * viewRatio
        bmp = bmp.Crop(bmp.Width / 2 - NewWidth / 2, 0, NewWidth, bmp.Height)
    End If
    Dim scale As Float = 1
    #if B4i
    scale = GetDeviceLayoutValues.NonnormalizedScale
    #End If
    ImageView.SetBitmap(bmp.Resize(ImageView.Width * scale, ImageView.Height * scale, True))
End Sub

Sub FileToBase64 (Dir As String, FileName As String) As String
    Dim su As StringUtils
    If Dir = "" Or FileName = "" Then Return ""
    Return su.EncodeBase64(Bit.InputStreamToBytes(File.OpenInput(Dir, FileName)))
End Sub

#IF B4J
Public Sub FileToBase64String
    Private fc As FileChooser
    fc.Initialize
    fc.Title="Browse and select a file"
    fc.SetExtensionFilter("Image", Array As String ("*.jpg", "*.png", "*.gif"))
    fc.InitialFileName = ""
    Private FileName As String = fc.ShowOpen(MainForm)   'this is the FileChooser

    NewPath = File.GetFileParent(FileName)
    NewFile = File.GetName(FileName)
    
'    Private Base64String As TextField
    Base64Text.Text = FileToBase64(NewPath, NewFile)
    Dim bmp As B4XBitmap = xui.LoadBitmap(NewPath, NewFile)
    FitImageToView(bmp, ImageView1)
    
End Sub
#END IF

#End Region         ' --- ImageRoutines
 
Upvote 0
Top