Android Question rotate a non square bitmap with transparent parts

Toni

Member
Licensed User
Longtime User
Hello,
I tried out everything I found in the forum but no code example works for me.
I flipped the bitmap of an non square and partly transparent imageview and it works fine. I've tried to translate this to
a rotating sub to do in the same manor, but find no working solution. I tried also out a DestRec with dip values thatare
explicit larger than a 45° rotated bitmap of my imageview, but at the end even when I change width and height for the
imageview the dimension stay as initial values. For rotating square bitmaps the code works fine. I know that I have to
recalculate left and top for non square bitmaps but that should be a peace of cake, even for me :rolleyes:
Any hints please? Thanks in advance!

rotating a bitmap:
Sub Gesture_onPointerDown(ptrIndex As Int, PID As Int, MotionEvent As Object)
    ' flipp image works fine
    Dim i As ImageView
    i=Sender
    Dim j As Int=i.tag  

    Dim vert As Boolean, hor As Boolean
    Dim bmp As Bitmap=i.bitmap
    Dim bmpflip As Bitmap
    bmpflip.InitializeMutable(bmp.width, bmp.height)
    Dim cv As Canvas
    cv.Initialize2(bmpflip)  
    cv.DrawColor(Colors.ARGB(0, 0, 0, 0))                                   ' 0 means fully transparent
    If bmp.Width>bmp.Height Then
        vert=True
        hor=False
    Else
        vert=False
        hor=True
    End If
    Dim DestRect As Rect
    DestRect.Initialize(0dip, 0dip, bmp.Width, bmp.height)
    cv.DrawBitmapFlipped(bmp, Null, DestRect, vert, hor) 
    i.Bitmap=bmpflip
    i.Invalidate
End Sub

Sub Gesture_onDoubleTap(X As Float, Y As Float, MotionEvent As Object)
' rotating  the bitmap works not
    Dim i As ImageView
    i=Sender
    Dim j As Int=i.tag   
    Dim bmp As Bitmap=i.bitmap
    Dim bmprot As Bitmap
    bmprot.InitializeMutable(bmp.width, bmp.height)
    Dim cv As Canvas
    cv.Initialize2(bmprot)
    cv.DrawColor(Colors.ARGB(0, 0, 0, 0))                           ' 0 means fully transparent
    Dim DestRect As Rect
    DestRect.Initialize(0dip, 0dip, bmp.Width, bmp.height)            ' also tried changing width and height, 210dip x 210dip or added a multiplyer to  width and height
    cv.DrawBitmaprotated(bmp, Null, DestRect, 90)
    i.Bitmap=bmprot                                           ' also tried setLayoutAnimated(0, i.left, i.top, new width, new height)
    i.Invalidate
end sub
 

Sagenut

Expert
Licensed User
Longtime User
What exactly is the problem?
Using Bitmap.Rotate does not make the job?
 
Upvote 0

klaus

Expert
Licensed User
Longtime User
Do you really need to draw the rotated bitmap.
Can't you not just rotate the ImageView or Panel.
Declare the views as B4XView and you can rotate those around the center.
If you need other rotations you may have a look HERE.
 
  • Like
Reactions: zed
Upvote 0

Toni

Member
Licensed User
Longtime User
@Sagenut: I'll try rotate but I think I'd tried it out before but not sure. Thanks!
@klaus: No, unfortunalty if I rotate the whole view dragging got fuzzy.
I 'll take a look to your link. Thanks!

Edit: @Sagenut: tried out bitmap.rotate. Maybe I do something wrong, but no success on non square imageview.
@klaus: rotating with javaobject works, but a following dragging routine leads also to fuzzy jumping of the view.
 
Last edited:
Upvote 0

Toni

Member
Licensed User
Longtime User
Here it comes... The rotation works for square pieces like the 3 blocks piece looks like a corner. The origin plan was to do a smooth animation of the 90° rotation. But now I'll be satisfied is it rotate 90°. If I ever finish it :cool:, it will be a mixture of tetris and tangram.

Edit: Interesting, if I shift the code to the button_click it works without any fuzzy behavior.

code owned by a button:
Private Sub btnPause_Click
'    Dim i As ImageView
'    i=Sender
    Dim j As Int            '=i.tag
    Dim w, h As Int
    j=5                        ' no5 as an example
    w=piece(j).Width
    h=piece(j).Height
    Dim bmp As Bitmap=piece(j).bitmap
    Dim bmprot As Bitmap
    bmprot.InitializeMutable(210dip, 210dip)
    Dim cv As Canvas
    cv.Initialize2(bmprot)
    cv.DrawColor(Colors.ARGB(0, 0, 0, 0))                           ' 0 means fully transparent
    Dim DestRect As Rect
    DestRect.Initialize(0dip, 0dip, 210dip, 210dip)            ' also tried changing width and height, 210dip x 210dip or added a multiplyer to  width and height
    cv.DrawBitmaprotated(bmp, Null, DestRect, 90)
    bmprot.Resize(h,w,True)
    piece(j).SetLayout(piece(j).Left,piece(j).Top,h,w)
    piece(j).Bitmap=bmprot                                           ' also tried setLayoutAnimated(0, i.left, i.top, new width, new height)
    piece(j).Invalidate
End Sub
 

Attachments

  • game.zip
    16.9 KB · Views: 11
Last edited:
Upvote 0

zed

Well-Known Member
Licensed User
Declare the views as B4XView and you can rotate those around the center.
Screenshot_20251123-090733.png
 
Upvote 0

Toni

Member
Licensed User
Longtime User
Thanks zed, but did you try it with the gesturedetector? I can't bring it to work.

Edit: I tried following code found on the internet, but my pieces disapear. What's wrong?

B4X:
Sub Gesture_onDoubleTap(X As Float, Y As Float, MotionEvent As Object)
    Dim i As B4XView
    i=Sender
    Dim j As Int=i.tag
    Dim bmp As B4XBitmap=piece(j).Bitmap
    piece(j).Bitmap=RotateBitmap(bmp, 90)
End Sub



Sub RotateBitmap (B4Xbmp As B4XBitmap, degrees As Float) As B4XBitmap
    Dim cvs As B4XCanvas
    Dim panel As B4XView = XUI.CreatePanel("")
    Dim rectTest As B4XRect
    rectTest.Initialize(0, 0, B4Xbmp.Width, B4Xbmp.Height)
    panel.Width = B4Xbmp.Width * Abs(CosD(degrees)) + B4Xbmp.Height * Abs(SinD(degrees))
    panel.Height = B4Xbmp.Width * Abs(SinD(degrees)) + B4Xbmp.Height * Abs(CosD(degrees))
    rectTest.Initialize(B4Xbmp.Height * Abs(SinD(degrees)) / 2, B4Xbmp.Width * Abs(SinD(degrees)) / 2, B4Xbmp.Width + B4Xbmp.Height * Abs(SinD(degrees)) / 2, B4Xbmp.Height + B4Xbmp.Width * Abs(SinD(degrees)) / 2)
    cvs.Initialize(panel)
    cvs.DrawBitmapRotated(B4Xbmp, rectTest, degrees)
    Dim b As B4XBitmap = cvs.CreateBitmap
    cvs.Release
    Return b
End Sub
 
Last edited:
Upvote 0

zed

Well-Known Member
Licensed User
Image rotation:
Instead of using Canvas.DrawBitmapRotated (which cropped or reduced the images), we used the Android Matrix API via JavaObject.
Matrix.postRotate(angle) applies an exact rotation.
Bitmap.createBitmap(..., matrix, True) generates a new rotated bitmap with the correct bounding box.

Sizing adjustments: After rotation, we update the width and height of the ImageView to match the new dimensions of the bitmap. This avoids the "smaller image" or "cropped image" effect.

Handling pieces of different sizes: Like in Tetris, each piece can have a different width/height ratio. At 90° or 270°, we swap the width and height to ensure the piece remains consistent on the grid.


See the screenshots

Before DoubleTap
1.png


After DoubleTap
2.png
 

Attachments

  • ProjectRotate.zip
    20.7 KB · Views: 6
Last edited:
Upvote 0

Toni

Member
Licensed User
Longtime User
Hi zed,
thank you for your patience with me. I see your screenshots and was glad that the problem seems to be solved. I'am quite sure that you solved the problem but even I installed your code several times without any changes, I've got the same problem as before. There are just three messages: that test.png is missing, BCCreator library is not used and that I should use targetSDKversion 35 instead of 34. Mmmmh, SDK36 is installed, but in the manifest is written 35 at my game example. Could that be the problem that SDK 36 (which is installed on my laptop) makes the problem?? Or any other ideas?
 
Upvote 0

Toni

Member
Licensed User
Longtime User
I just see in the SDK manager that a lot of extensions are not installed. If I search for matrix I get a message to install all extensions is recommended.
Is that true? I ask why I do not find "select all". And how can I choose all at once because that are a lot of extensions
 
Upvote 0

klaus

Expert
Licensed User
Longtime User
I tested zed's program.
It works, but i get this when double clicking on an ImageView.

Moving a view:

1763922738046.png


And then, double tabbing on it, i get this :

1763922866559.png


This shows that the width and height are not taken into account.
It seems that GestureDetection keeps the 'old' dimensions of the view.
 
Upvote 0
Top