Android Question Add thumbnail with WriteToStream method

Ivan Aldaz

Member
Licensed User
Longtime User
Hi all.

I´m trying to add a thumbnail to a picture modified in a canvas. The original picture has a thumbnail 'inside', but the one generated with 'OutPutStream' and the 'WriteToStream' method doesn't have it.

Executing the code attached below you can see the result in the 'Logs' window. You'll need the 'JpegUtils' library.

Is there any way to add or append a thumbnail to a .jpg file generated this way? I know 'LoadBitmapSample', but it creates a new file, and that's not what I'm looking for. I want the thumbnail in the same file as the picture, like in the original picture.

B4X:
Sub Activity_Create(FirstTime As Boolean)

Dim exif As ExifData
Dim canvas1 As Canvas
Dim bitmap1, bitmap2 As Bitmap
Dim brect As Rect
Dim iv As ImageView
     
File.Copy(File.DirAssets, "Sample.jpg", File.DirRootExternal,"Sample.jpg")

    bitmap1.Initialize(File.DirRootExternal, "sample.jpg")
    bitmap2.InitializeMutable(bitmap1.Width,bitmap1.Height)
    canvas1.Initialize2(bitmap2)
    brect.Initialize(0,0,bitmap1.Width, bitmap1.Height)


'Add picture to canvas
    canvas1.DrawBitmap(bitmap1, Null, brect)
   
'Add a circle to canvas
    canvas1.DrawCircle(100dip, 100dip, 40dip, Colors.Red, False, 10dip)
   
'Show modified picture
    iv.Initialize("iv")
    iv.Bitmap=canvas1.Bitmap
    iv.Gravity = Gravity.FILL

 Activity.AddView(iv,0,0,100%x, 100%y)

'Save picture 
    Dim Out As OutputStream
    Out = File.OpenOutput(File.DirRootExternal, "SampleWithCircle.jpg", False)
    canvas1.Bitmap.WriteToStream(Out, 100, "JPEG")
    Out.Close

'This code does'n work to add a thumb
    Dim thumb As Bitmap = LoadBitmapSample(File.DirRootExternal, "SampleWithCircle.jpg", 100dip, 100dip)
'    Dim Out2 As OutputStream
'    Out2 = File.OpenOutput(File.DirRootExternal, "SampleWithCircle.jpg", True)
'    thumb.WriteToStream(Out2,100,"JPEG")
'    Out2.Close

'Test if "Sample.jpg" has thumbnail
    exif.Initialize(File.DirRootExternal, "Sample.jpg")
    Log("Sample has thumbnail: " & exif.hasThumbnail)              

'Test if "SampleWithCircle.jpg" has thumbnail
    exif.Initialize(File.DirRootExternal, "SampleWithCircle.jpg")
    Log("SampleWithCircle has thumbnail: " & exif.hasThumbnail)  
   
End Sub

Thanks in advance.
 

Attachments

  • Sample.jpg
    Sample.jpg
    283.9 KB · Views: 308

Ivan Aldaz

Member
Licensed User
Longtime User
Thank you for your promt answer, eps

Maybe I have to convert the bitmap to a string, but the only way I see that the thumbnail could be added is by "exif.setAttribute (tag As java.lang.String, value As java.lang.String) As void". Post #2 in that thread shows all the exif tags, but don't find the one that could match.
 
Upvote 0

eps

Expert
Licensed User
Longtime User
I don't know - you'll have to investigate...

Maybe extract the exif you have in the original image which 'works' and then work backwards?

There are :

ThumbnailImageLength - null
ThumbnailImageWidth - null
 
Upvote 0

Ivan Aldaz

Member
Licensed User
Longtime User
But then I'd have the thumbnail of the unmodified picture. There must be a method in Java that writes the exif thumbnail, so I could use with r.Runmethod(...), but I don't find it...
 
Upvote 0

eps

Expert
Licensed User
Longtime User
that's just the size of the thumbnail..

You also need to look at (from the link above)

Properties:
  • ThumbnailRange As long[] [read only]
  • ThumbnailBytes As byte[] [read only]
  • GpsDateTime As long [read only]
  • ThumbnailBitmap As android.graphics.Bitmap [read only]
  • Thumbnail As byte[] [read only]
  • DateTime As long [read only]
 
Upvote 0

Ivan Aldaz

Member
Licensed User
Longtime User
Thank you again for your time, eps

I've seen that properties in the link above, but all of them are [read only], and all I get is information about the thumbnail that is already embedded in the picture.
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
and all I get is information about the thumbnail that is already embedded in the picture.
Can you upload such a Picture with embedded thumbnail?
I tried the pic above and the ExifInterface does not return any information about the/a thumbnail.
 
Upvote 0

Ivan Aldaz

Member
Licensed User
Longtime User
Hi, DonManfred.

I've tried with the uploaded image, and think the thumbnail is there. It can be shown by adding the next code after exif.Initialize (the first two lines are not new):

B4X:
    exif.Initialize(File.DirRootExternal, "Sample.jpg") 'This lines are not new
    Log("Sample has thumbnail: " & exif.hasThumbnail)
   
   
    Dim ivThumb As ImageView
    ivThumb.Initialize("ivThumb")
    ivThumb.Bitmap= exif.DecodeThumbnail(exif.Thumbnail)
    ivThumb.Gravity = Gravity.FILL

    Activity.AddView(ivThumb,5%x, 80%y,100dip, 100dip)

But don't see any value the properties either.

B4X:
    Log("Thumb Length: " & exif.getAttribute("ThumbnailImageLength")) 
    Log("Thumb Width: " & exif.getAttribute("ThumbnailImageWidth"))
 
Upvote 0

Ivan Aldaz

Member
Licensed User
Longtime User
I've tried this (code taken from an answer by Erel in another thread), using this (https://developer.android.com/reference/android/media/ExifInterface.html):

B4X:
Dim exif As JavaObject
     exif.InitializeNewInstance("android.media.ExifInterface", Array(File.Combine(File.DirRootExternal, "SampleWithCircle.jpg")))
    exif.RunMethod("setAttribute", Array(ExifConst("TAG_ORF_THUMBNAIL_IMAGE"),thumb))
     exif.RunMethod("saveAttributes", Null)
   


Private Sub ExifConst(tag As String) As String
    Dim jo As JavaObject
    Return jo.InitializeStatic("android.media.ExifInterface").GetField(tag)
End Sub


But doesn'twork too. I get this error message:

"java.lang.RuntimeException: Field: TAG_ORF_THUMBNAIL_IMAGE not found in: android.media.ExifInterface"
 
Upvote 0

Ivan Aldaz

Member
Licensed User
Longtime User
Hi. The post I took the code from is https://www.b4x.com/android/forum/threads/big-exif-data-in-jpeg.74468/#post-472932

Just changed

B4X:
ExifConst("TAG_ARTIST"), "John Due")

for

B4X:
ExifConst("TAG_ORF_THUMBNAIL"), thumb)

with
B4X:
 thumb = loadBitmapSample(File.DirRootExternal,"SampleWithCircle.jpg", 50dip, 50dip)

but didn't know that "TAG_ORF_THUMBNAIL_IMAGE is only available in Android O.". I saw this label in exifInterface.html and tried.
 
Upvote 0

Ivan Aldaz

Member
Licensed User
Longtime User
I understand, of course you won't post a non-working code. That's why I wrote 'using this' ... 'and this'. The second 'this' was used to take the constant and change it on your code.

My apologies.
 
Upvote 0
Top