B4J Question [Solved] B4XCanvas DrawBitmap causes loss of quality

CaptKronos

Active Member
Licensed User
Longtime User
I have only just noticed that the following code causes the bitmap's quality to be reduced. It's almost like it has been blurred. Can someone point me to the solution?
Thanks.

B4X:
    Dim bc As BitmapCreator
    Dim bmp As B4XBitmap= xui.LoadBitmap(File.DirAssets, "test.jpg")
    bc.Initialize(bmp.Width, bmp.Height)
    bc.CopyPixelsFromBitmap(bmp)
    ImageView1.SetBitmap(bc.Bitmap) 'looks good here

    BasePanel=xui.CreatePanel("")
    BasePanel.SetLayoutAnimated(0,0,0,bmp.Width,bmp.Height)
    Dim cnv As B4XCanvas
    cnv.Initialize(BasePanel)
    cnv.DrawBitmap(bc.Bitmap, cnv.TargetRect)
    ImageView1.SetBitmap(cnv.CreateBitmap) 'looks bad here'

beforeDrawBitmap.jpg
afterDrawBitmap.jpg
 
Solution
Just discovered the solution to this issue here: https://www.b4x.com/android/forum/threads/disabling-anti-aliasing-on-text.159711/post-980525

Referring back to the code in my opening post:

B4X:
    Dim bc As BitmapCreator
    Dim bmp As B4XBitmap= xui.LoadBitmap(File.DirAssets, "test.jpg")
    bc.Initialize(bmp.Width, bmp.Height)
    bc.CopyPixelsFromBitmap(bmp)
    ImageView1.SetBitmap(bc.Bitmap) 'looks good here
    BasePanel=xui.CreatePanel("")
    BasePanel.SetLayoutAnimated(0,0,0,bmp.Width,bmp.Height)
    Dim cnv As B4XCanvas
    cnv.Initialize(BasePanel)

    '**** add the following line *****
    GetNativeCanvas(cnv).As(JavaObject).RunMethodjo("getGraphicsContext2D",Null).RunMethod("setImageSmoothing",Array(False))...

peacemaker

Expert
Licensed User
Longtime User
B4X:
Sub Class_Globals
    Private Root As B4XView
    Private xui As XUI
    Private BasePanel As B4XView
    Private ImageView1 As B4XView
    Private ImageView2 As B4XView
    Dim Scale As Float                'added
End Sub

Public Sub Initialize
'    B4XPages.GetManager.LogEvents = True
    Dim fx As JFX
    Scale = fx.PrimaryScreen.As(JavaObject).RunMethod("getOutputScaleX", Null)
End Sub

Private Sub Button1_Click
    Dim bc As BitmapCreator
    Dim bmp As B4XBitmap= xui.LoadBitmap(File.DirAssets, "test.jpg")
    ImageView1.Width=bmp.Width
    ImageView1.Height=bmp.Height
    bc.Initialize(bmp.Width, bmp.Height)
    bc.CopyPixelsFromBitmap(bmp)
    ImageView1.SetBitmap(bc.Bitmap)
'    xui.MsgboxAsync("looks good at this point...", "")
'    Wait For Msgbox_Result (Result As Int)
    ImageView2.Width=bmp.Width
    ImageView2.Height=bmp.Height
    BasePanel=xui.CreatePanel("")
    
    BasePanel.SetLayoutAnimated(0,0,0,bmp.Width * Scale,bmp.Height * Scale)   'corrected
    
    Dim cnv As B4XCanvas
    cnv.Initialize(BasePanel)
    cnv.DrawBitmap(bc.Bitmap, cnv.TargetRect)
    ImageView2.SetBitmap(cnv.CreateBitmap)
End Sub
 
Upvote 0

CaptKronos

Active Member
Licensed User
Longtime User
Thanks peacemaker. Visually that works, but my problem is that we now have a bitmap with twice the dimensions as the original one. In my app, I'm going to be processing the bitmap further, so changing its size will cause me a problem.
 
Upvote 0

peacemaker

Expert
Licensed User
Longtime User
Use the size correction only once, at final showing. Other pre-processing with default bitmap.
 
Upvote 0

CaptKronos

Active Member
Licensed User
Longtime User
I need to fill you in on what I'm trying to do. My app uses a B4XCanvas to create a graph (as per the example bitmap) with the axis text etc which I then convert to a BitmapCreator in order to add the fancy gradient under the graph's plot, and finally I copy the pretty graph back to the B4XCanvas for further processing and storage. The BitmapCreator "prettyfying" is just a nice to have addition to an existing app. I can live without it, but I'm so close...
 
Upvote 0

peacemaker

Expert
Licensed User
Longtime User

think yourself. this topic is out.
 
Upvote 0

CaptKronos

Active Member
Licensed User
Longtime User
Just discovered the solution to this issue here: https://www.b4x.com/android/forum/threads/disabling-anti-aliasing-on-text.159711/post-980525

Referring back to the code in my opening post:

B4X:
    Dim bc As BitmapCreator
    Dim bmp As B4XBitmap= xui.LoadBitmap(File.DirAssets, "test.jpg")
    bc.Initialize(bmp.Width, bmp.Height)
    bc.CopyPixelsFromBitmap(bmp)
    ImageView1.SetBitmap(bc.Bitmap) 'looks good here
    BasePanel=xui.CreatePanel("")
    BasePanel.SetLayoutAnimated(0,0,0,bmp.Width,bmp.Height)
    Dim cnv As B4XCanvas
    cnv.Initialize(BasePanel)

    '**** add the following line *****
    GetNativeCanvas(cnv).As(JavaObject).RunMethodjo("getGraphicsContext2D",Null).RunMethod("setImageSmoothing",Array(False))

    cnv.DrawBitmap(bc.Bitmap, cnv.TargetRect)
    ImageView1.SetBitmap(cnv.CreateBitmap) 'looks good here as well!!!
    
    
    
Sub GetNativeCanvas (b4x As B4XCanvas) As Canvas
    Dim jo As JavaObject = b4x
    jo = jo.GetFieldJO("cvs")
    If xui.IsB4J Then Return jo.RunMethod("getObject", Null)
    Return jo
End Sub
 
Upvote 1
Solution
Top