Wish DrawBitmap no source rectangle

klaus

Expert
Licensed User
In B4A the DrawBitmap method has a SourceRectangle parameter to draw a part of the source bitmap.
In B4i the SourceRectangle parameter is missing.
Same for DrawBitmapRotated.
Is this an iOS limitation ?
 

Erel

Administrator
Staff member
Licensed User
There is no native API for this like in Android. However you can use these two methods to implement it:
B4X:
Sub DrawBitmapRotated(canvas1 As Canvas, Bitmap1 As Bitmap, SrcRect As Rect, DestRect As Rect, Degrees As Float)
   Dim no As NativeObject = canvas1
   no.RunMethod("rotate:::", Array(Degrees, DestRect.CenterX, DestRect.CenterY))
   DrawBitmap(canvas1, Bitmap1, SrcRect, DestRect)
   no.RunMethod("rotate:::", Array(-Degrees, DestRect.CenterX, DestRect.CenterY))
End Sub

Sub DrawBitmap(canvas1 As Canvas, Bitmap1 As Bitmap, SrcRect As Rect, DestRect As Rect)
   If SrcRect = Null Then
     Dim SrcRect As Rect
     SrcRect.Initialize(0, 0, Bitmap1.Width, Bitmap1.Height)
   End If
   Dim p1 As Path
   p1.InitializeRect(DestRect, 0)
   canvas1.ClipPath(p1)
   Dim sx, sy As Float
   sx = (DestRect.Right - DestRect.Left) / (SrcRect.Right - SrcRect.Left)
   sy = (DestRect.Bottom - DestRect.Top) / (SrcRect.Bottom - SrcRect.Top)
   Dim x, y, width, height As Int
   x = DestRect.Left - sx * SrcRect.Left
   y = DestRect.Top - sy * SrcRect.Top
   width = Bitmap1.Width * sx
   height = Bitmap1.Height * sy
   Dim d2 As Rect
   d2.Initialize(x, y, x + width, y + height)
   canvas1.DrawBitmap(Bitmap1, d2)
   canvas1.RemoveClip
End Sub
They behave like B4A DrawBitmap and DrawBitmapRotated.
 

sorex

Expert
Licensed User
I don't want to sound harsh but...

isn't it the purpose of B4x to stick to the same common methods/syntax in all tools to make it easier for us switching between B4A/B4i/B4J?

why wasn't it added to the core like this in the first place so that our copy paste of code would've worked?

don't feel offended but i'm getting into one surprise after the other while expecting it to be more simular.
 

Erel

Administrator
Staff member
Licensed User
isn't it the purpose of B4x to stick to the same common methods/syntax in all tools to make it easier for us switching between B4A/B4i/B4J?
It is one of the purposes. However when the native APIs are too different there is always a tension between building a thick abstraction above the native APIs vs. a thin abstraction. There is a price for thick abstractions.

As you can see in the above code, creating a DrawBitmap method that is identical to B4A DrawBitmap method requires quite a lot of "heavy" work (atruntime). In this case I decided to follow the native API which I believe provides the feature required in 95%+ of the cases (where you want to draw the full bitmap). In the other cases you can use the code I posted here.
 

Erel

Administrator
Staff member
Licensed User
don't feel offended but i'm getting into one surprise after the other while expecting it to be more simular.
Not offended. iOS and Android are very different platforms. As someone who is deeply familiar with both platforms I'm very happy with the amount of code that can be reused between the platforms. More importantly, B4i follows the same concepts of B4A and B4J which means that it should not be too difficult for a developer to switch from one platform to another.
 

sorex

Expert
Licensed User
I will put a thread in the tutorials section about the changes I went through for a simple game I ported from B4A > B4i.

It might be handy reference for some people.

It just took an evening which is still faster than writing it from scratch.
 

iCAB

Well-Known Member
Licensed User
Hi Guys

I am trying to achieve the exact same result in B4I for the code below

B4X:
Sub RotateImage(original As Bitmap, degree As Float) As Bitmap
   Dim matrix As JavaObject
   matrix.InitializeNewInstance("android.graphics.Matrix", Null)
   matrix.RunMethod("postRotate", Array(degree))
   Dim bmp As JavaObject
   bmp.InitializeStatic("android.graphics.Bitmap")
   Dim NewImage As Bitmap = bmp.RunMethod("createBitmap", Array(original, 0, 0, original.Width, original.Height, _
     matrix, True))
   Return NewImage
End Sub

I would to be able to save the returned image.

Thank you
 
Top