iOS Tutorial DrawBitmapRotated over ImageView

Mark Turney

Active Member
Licensed User
The latest version of my Face Flashcards app (waiting for review) had one issue that was nagging me. I had used the designer to create an imageview called "flashCards", for which a randomly selected picture was to be placed after retrieval from SQLite. The problem began with the image being landscape after retrieval from SQL. I took the image in portrait orientation, and initially it showed as portrait in the immediate post-"snap" preview. However, after saving and then retrieving from SQLite, apparently the exif data related to orientation was lost.

The flashCards imageview was set to a Content Mode of Fill, so that the picture would re-size itself automatically to fit the dimensions I wanted. If I started by just using flashCards.bitmap = returnedPic, the image would fill the imageview but was in landscape mode and therefore the x/y dimensions were reversed secondary to the automatic sizing of the fill content mode. Of course, I didn't want the image in landscape orientation anyway, so I looked at using the DrawBitmapRotated(Bitmap as Bitmap, DestRect as Rect, Degrees as Float) member. In a nutshell, if you are rotating a rectangle as opposed to a square, you have to remember that DrawBitmapRotated rotates the rectangle around the center. Therefore, you have to know what starting top/left and bottom/right coordinates to use so that when rotated, the rectangle will fill the imageview as you designed it.

Here's a graphic showing what I mean:

upload_2015-1-6_9-5-3.png


And, here is the code that queries the name and picture from SQLite, and populates the imageview correctly after rotation:

B4X:
Sub ReadBlob                                                                        'Reads pic and name from SQL
    rs = sql1.ExecQuery("select name, picture from table1")
  
    Dim rowCnt As Int
    Dim InputStream1 As InputStream
    Dim Rect1 As Rect
  
    Dim rotDiff As Int
    Dim startL, startT, startR, startB As Int
    rotDiff = (flashCards.Height - flashCards.Width)/2
    startL = -rotDiff
    startT = rotDiff
    startR = flashCards.Width + rotDiff
    startB = flashCards.Height - rotDiff
  
    rowCnt = 0
  
    Do While rs.NextRow
        rowCnt = rowCnt + 1
        If rowCnt = selectedRndRow Then
            returnedName = rs.GetString("name")
            Buffer = rs.GetBlob("picture")
            InputStream1.InitializeFromBytesArray(Buffer, 0, Buffer.Length)
            returnedPic.Initialize2(InputStream1)
            InputStream1.Close
            canvas1.Initialize(flashCards)
            Rect1.Initialize(startL, startT, startR, startB)
            canvas1.DrawBitmapRotated(returnedPic, Rect1, 90)   
            canvas1.Refresh
        End If
    Loop
End Sub
Another snippet of code I would like to share ensures that the image maintains its 2:3 dimensions even while screen sizes change. This code is in the Designer Scripts for the Flashcards page:

B4X:
xDiv = 100%x / 3
flashCards.Width = 2 * xDiv
flashCards.Height = 3 * xDiv
flashCards.HorizontalCenter = 50%x
flashCards.VerticalCenter = 45%y
The code and graphic should explain how all this works. But, please feel free to ask me if any of this doesn't make sense. It works perfectly now in my app.
 
Top