Android Question Write text in photo [Solved]

carlos7000

Well-Known Member
Licensed User
Longtime User
Hi.

I am trying to create a simple application that marks the photos with the time and geographical coordinates. I'm doing it with CameraEx.
The problem I have is that I have to wait for CameraEx to create a Jpg file, then open it and mark the photo, and then save it again, which degrades the image.

I think that the function of the CameraEx that receives the data to save it as a .jpg file is

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

¿How to convert the data of the Variable Data that are of the Byte type to be able to pass them to a function that I found in the forum that only receives a bitmap?

I would like to modify, for example, the SavePictureToFile function so that it looks like this:

B4X:
Public Sub SavePictureToFile (Data () As Byte, Dir As String, FileName As String)

    'Function to create and what would process the data before saving
    Data = WriteTextInPicture (Data, "hello world") '<--- Function that I would like to create

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

For now, what I have to do is load the jpg generated by the application and postprocess the image

B4X:
Sub Camera1_PictureTaken (Data () As Byte)
    Dim filename As String = Other.GetDateTime & ".jpg"
    Dim dir As String = File.DirInternal
    Dim f As X_Files
    f.Initialize
    dir = f.GetTargetDir

    camEx.SavePictureToFile (Data, dir, filename)
    camEx.StartPreview 'restart preview
    ToastMessageShow ("Picture saved." & CRLF & "File size:" & File.Size (dir, filename) & CRLF & dir &     "/" & filename, True)

    'Function that postprocesses photography.
    Others.WriteTextInPhoto (LoadBitmap (dir, filename), LabelTexto.Text)  '<--- Function with which to postprocess the image taken by CameraEx
End Sub

The Prosprocessing Function is this

B4X:
Sub WriteTextInPhoto (Photo As Bitmap, Text As String) 'dir As String, filename As String
    Dim IV As ImageView
    Dim brect As Rect
    Dim canvas As Canvas
    Dim out As OutputStream
    Dim X As X_Files
    Dim NewName As String

    X.Initialize

    Image.InitializeMutable (Image.Width, Image.Height)
    IV.Initialize ("tmp")   
    IV.Bitmap = Photo
    IV.Height = Photo.Height
    IV.Width = Photo.Width

    b = IV.Bitmap
    brect.Initialize (0, 0, IV.Width, IV.Height)

    canvas.Initialize (IV)
    canvas.DrawColor (Colors.White)
    canvas.DrawBitmap (b, Null, brect)
    canvas.DrawText (Text, IV.Width / 2, IV.Height - 10dip, Typeface.DEFAULT, 40, Colors.Cyan, "CENTER")
    IV.Invalidate

    b = IV.Bitmap

    NewName = GetDateTime
    out = File.OpenOutput (X.GetTargetDir, NewName & ".jpg", False)
    b.WriteToStream (out, 95, "JPEG")
    out.Close
End Sub

Note: I did not write the function. I found it in some forum and copied it. I would like to give credit to those who wrote it but I can't find the post.

I have not modified the function, although I notice that there are things that can be improved, because I do not understand completely understand how it works.
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
1. Don't initialize the Canvas and the mutable bitmap each time. Reuse them as they will require a lot of memory.

The problem I have is that I have to wait for CameraEx to create a Jpg file, then open it and mark the photo, and then save it again, which degrades the image.
It doesn't degrade the image.

You can load a bitmap from an array of bytes with:
B4X:
Dim in As InputStream
in.InitializeFromBytesArray(Data, 0, Data.Length)
Dim bmp As Bitmap
bmp.Initialize2(in)
in.Close

Note that you cannot resize the image when you load it like this as you can do with LoadBitmapResize.
 
Upvote 0

carlos7000

Well-Known Member
Licensed User
Longtime User
1. Don't initialize the Canvas and the mutable bitmap each time. Reuse them as they will require a lot of memory.


It doesn't degrade the image.

You can load a bitmap from an array of bytes with:
B4X:
Dim in As InputStream
in.InitializeFromBytesArray(Data, 0, Data.Length)
Dim bmp As Bitmap
bmp.Initialize2(in)
in.Close

Note that you cannot resize the image when you load it like this as you can do with LoadBitmapResize.

It works very well.
Thank you.
 
Upvote 0
Top