Android Question File Rotation... Can't Get It Done!

Shadow&Max

Active Member
Licensed User
Longtime User
This is weird.

I can rotate the bitmap ok, but the actual container doesn't change.

I want to rotate a bitmap that's in portrait mode, to landscape, and save it as that landscape size. It appears that when I rotate the bitmap, and save it, it's saved as the horizontal picture, inside a portrait container, much of which is black above and below the rotated pic. So, in what's saved, I end up with the rotated image the width of which is the width of the portrait container and the height is only a small portion of the portrait picture, but the rotated picture is in the correct proportions.

I've tried several of the things I found on the site, but still come up with the same result. Here's where I am now:

B4X:
Sub RotateView(v As View, bmp As Bitmap, degrees As Float)
    Dim c As Canvas
    Dim R As Rect
    'Dim imgratio As Long
    Dim hh2,hw2 As Int
    hh2 = v.Height
    hw2 = v.Width

    c.Initialize(v)
    R.Initialize(0,0,v.Height,v.Width)
    c.DrawRect(R,Colors.transparent,True,0)
    c.DrawBitmapRotated(bmp,Null,R,degrees)
   
    v.SetBackgroundImage(c.Bitmap)

    v.Invalidate
   
    Dim out As OutputStream
    Dim rfile As String
   
    rfile = "rotatetemp.jpg"
    out = File.OpenOutput(File.DirInternal, rfile, False)
    c.Bitmap.WriteToStream(out, 100, "JPEG")
    out.Close
    ResizePreviewPhoto(File.DirInternal,rfile)
    SetPreviewLayout

End Sub

Sub SetPreviewLayout  '(bwidth As Int, bheight As Int)

    'ivPreview.Height = bwidth
    'ivPreview.Width = bheight
   
    ivPreview.Top = (btnShoot.Top / 2) - (ivPreview.Height / 2)
    ivPreview.Left = iv.Left + ((iv.Width / 2) - (ivPreview.Width / 2) )
    DoEvents
    btnRotateLeft.Top = (ivPreview.Top + ivPreview.Height / 2) - btnRotateLeft.Height / 2
    btnRotateRight.Top = btnRotateLeft.Top
    btnRotateLeft.Left = ivPreview.Left - btnRotateLeft.Width - 20dip
    btnRotateRight.Left = ivPreview.Left + ivPreview.Width +  20dip   
End Sub

Sub ResizePreviewPhoto (Dir As String, FileName As String)
    Dim bm2 As Bitmap
    bm2.InitializeSample(Dir, FileName, 100dip, 100dip)
    hip = bm2.Height
    wip = bm2.Width
    ivPreview.Bitmap = bm2
        If hip = wip Then 'It's Square
            ivPreview.Height = 100dip
            ivPreview.Width = 100dip
        Else If hip > wip Then 'It's Portrait
            imageratio = (wip / hip)
            ivPreview.Height = 100dip
            ivPreview.Width = ivPreview.Height  * imageratio  '- 20dip
        Else 'It's Landscape
            imageratio = (hip / wip)
            ivPreview.Width = 100dip 'pnl.Width '- 40dip
            ivPreview.Height = ivPreview.Width * imageratio
        End If
End Sub

I don't know what to do next. This SHOULD work, shouldn't it? If not, where'd I go wrong here?
 

strat

Active Member
Licensed User
Longtime User
This works but causes some blur effects after rotation. I couldn't find why it occurs.




B4X:
'Needed Libraries : Reflection



Sub Process_Globals
End Sub

Sub Globals
    Dim masterpic As Bitmap
    Dim button1 As Button
    Dim button2 As Button
    Dim picture As ImageView
    Dim cnv As Canvas
End Sub

Sub Activity_Create(FirstTime As Boolean)
    button1.Initialize("button1")
    Activity.AddView(button1,20%x,90%y,30%x,10%y)
    button1.Text="Draw"
   
    button2.Initialize("button2")
    Activity.AddView(button2,60%x,90%y,30%x,10%y)
    button2.Text="Rotate"
   
    picture.Initialize("picture")
    Activity.AddView(picture,0,0,50%x,50%y)
End Sub

Sub button1_click
    cnv.Initialize(picture)
    For i=1 To 100
        cnv.DrawLine(Rnd(0,25%x),Rnd(0,25%y),Rnd(25%x,50%x),Rnd(25%y,50%y),Colors.ARGB(255,Rnd(50,255),Rnd(50,255),Rnd(50,255)),1)
    Next
   
End Sub

Sub button2_click
    masterpic.Initialize3(picture.Bitmap)
    masterpic.
    rotatepicture(30)'Rotate the picture 30 degree at every step
    picture.Bitmap=masterpic
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub rotatepicture( angle As Int)
  Dim bb As Bitmap
  Dim pwo As Int
  Dim sqp As Int
  Dim pho As Int
  Dim recto As Rect
  Dim c As Canvas
 
  pwo = masterpic.Width
  pho = masterpic.Height
  'pwo=100
  'pho=133
  sqp = pwo 'for square imaqe
 
  If pwo <> pho Then
      'set longer side
      sqp = pho
      If pwo > pho Then sqp = pwo
     
      'first RESIZE to square
      bb = CreateScaledBitmap (masterpic, sqp, sqp, True)
  End If
 
  bb.InitializeMutable(sqp,sqp)
  recto.Initialize(0, 0,sqp,sqp)

  'ROTATE masterPic into bb
  c.Initialize2(bb)
  c.DrawBitmapRotated(masterpic, Null, recto, angle) 'Draw the new image
  masterpic.Initialize3(bb)
 
  'RESIZE back inverse, if pic was not square
  If pwo <> pho Then
      masterpic = CreateScaledBitmap (bb, pho, pwo, True)
  End If
 
End Sub

Sub CreateScaledBitmap(Original As Bitmap, Width As Int, Height As Int, Filter As Boolean) As Bitmap
  Dim rf As Reflector
  Dim bm As Bitmap
  bm = rf.RunStaticMethod("android.graphics.Bitmap", "createScaledBitmap", _
  Array As Object(Original, Width, Height, Filter), _
  Array As String("android.graphics.Bitmap", "java.lang.int", "java.lang.int", "java.lang.boolean"))
  Return bm
End Sub
 
Upvote 0

Shadow&Max

Active Member
Licensed User
Longtime User
v is a imageview... ivPreview... 200h, 112 w originally...

What I'm doing here is this:

I have a pic on the original screen. I bring up a panel with a small preview pic, that gets rotated. When the user's happy with that, I'll take the temp file I'm creating during the rotation, and copy it over the original file on the original screen.

I'm not sure what the original dimensions of the picture are on the main screen. But I reload the picture into that ivPreview, manipulate it there, and then will go back. The problem is that the preview image is out of whack...

FYI, I wasn't saving the preview image at first, but I added the code because the preview pane would shrink in weird ways each time. The proportions never stayed the same, becoming thinner and thinner.

The original picture...

rotate1.PNG


The original preview pic:

rotate2.PNG


Rotated once:

rotate3.PNG


Rotated again:

rotate4.PNG
 
Last edited:
Upvote 0

Shadow&Max

Active Member
Licensed User
Longtime User
Sure... it happens with ALL pictures though...
 

Attachments

  • MVC-748F.jpg
    MVC-748F.jpg
    288.8 KB · Views: 478
Upvote 0

Shadow&Max

Active Member
Licensed User
Longtime User
Let me make sure I'm clear about what I'm trying to do...

The picture attached is on the main screen. When they click the edit button, the second shot comes up. In it is a preview made by calling ResizePreviewPhoto wit the dir and file name of the file that's in the main screen. ResizePreviewPhoto shrinks it down to the preview size.

I rotate the picture, as many times as the user wants, and then, when they're satisfied, I rotate the existing image and copy it to a temp file, and if they stay with it, delete the first, original file, and rename the temp file to a new name, then store it in the database...

When the preview opens, it's correct, as shown, on the first rotate, it shrinks, but the aspect is completely wrong.. Then, on the second rotate, it's smaller, but the aspect is correct as it's upside down portrait, but the smaller size. Then it rotates again and gets smaller once more... But at that smaller size it stays, but constantly degrades the background of the ivPreview ImageView to some pixilated mess.
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Based on this solution: http://stackoverflow.com/questions/...esults-in-squashed-image-need-a-true-rotate-b

B4X:
Sub Activity_Create(FirstTime As Boolean)
   Dim NewImage As Bitmap = RotateImage(LoadBitmap(File.DirAssets, "MVC-748F.jpg"), 180)
   Dim iv As ImageView
   iv.Initialize("")
   Activity.AddView(iv, 0, 0, NewImage.Width, NewImage.Height)
   iv.SetBackgroundImage(NewImage)
   iv.Gravity = Gravity.FILL
End Sub

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
 
Upvote 0

Shadow&Max

Active Member
Licensed User
Longtime User
Thanks Erel... I'll try this out and see how it goes... Really appreciate the feedback...
 
Upvote 0

Shadow&Max

Active Member
Licensed User
Longtime User
Thanks Erel... Took a while to get it right, but you put me on the right track. I had a lot of fudging to do with the two panels and multiple ImageViews... Got it though... Thanks!
 
Upvote 0

Shadow&Max

Active Member
Licensed User
Longtime User
Post some of your code so we can see what you're doing. I'm using that call without issue...
 
Upvote 0

squaremation

Active Member
Licensed User
Longtime User
Post some of your code so we can see what you're doing. I'm using that call without issue...

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

Shadow&Max

Active Member
Licensed User
Longtime User
Are you passing the degrees to rotate when you call this and is that number passed a variable?
 
Upvote 0

squaremation

Active Member
Licensed User
Longtime User
Are you passing the degrees to rotate when you call this and is that number passed a variable?

B4X:
Dim NewImage As Bitmap = RotateImage(LoadBitmap(File.DirAssets, "min.png"), 6)
 
Upvote 0

Shadow&Max

Active Member
Licensed User
Longtime User
Just as a test... call it something other than newimage in the call.

Also, I found that breaking the lines u helped me for some reason... maybe it was just visual, but I recall that I broke it up for a reason...

May be a shot in the dark because that same code is working fine for me, but try:

B4X:
Dim TestImage as Bitmap
TestImage = LoadBitmap(File.DirAssets, "min.png")
TestImage = RotateImage(TestImage, 6)
 
Last edited:
Upvote 0

squaremation

Active Member
Licensed User
Longtime User
Tried it no go :(

For some reason i can't get any methods to rotate a image to work.
I must be doing something wrong it seems straight forward, idk :confused:
 
Upvote 0

Shadow&Max

Active Member
Licensed User
Longtime User
When you tried that other code, did you get the same error or did it just not rotate?
 
Upvote 0

squaremation

Active Member
Licensed User
Longtime User
same error

B4X:
Sub Process_Globals
    Dim rv As RemoteViews
    Dim Timer01 As Timer
   
End Sub

Sub Service_Create
    rv = ConfigureHomeWidget("LayoutFile", "rv", 0, "Analog Clock Widget")

End Sub

Sub Service_Start (StartingIntent As Intent)
    If rv.HandleWidgetEvents(StartingIntent) Then Return
    Timer01.Initialize("Timer01", 60000) ' 1000 = 1 second
    Timer01.Enabled = True
End Sub
Sub Timer01_Tick
    rv_RequestUpdate
End Sub
Sub rv_RequestUpdate
    'Dim minhand As Bitmap = LoadBitmap(File.DirAssets, "min.png")
    'ShowMinute(minhand)
    'MinuteTick("min.png" As Bitmap)
    'Dim TestImage As Bitmap = RotateImage(LoadBitmap(File.DirAssets, "min.png"), 6)
    Dim TestImage As Bitmap
    TestImage = LoadBitmap(File.DirAssets, "min.png")
    TestImage = RotateImage(TestImage, 6)
    rv.UpdateWidget
End Sub
Sub rv_Disabled
    StopService("")
End Sub

Sub Service_Destroy

End Sub
'Sub ShowMinute(bmp As Bitmap)
'   
'      Dim rbmp As RSImageProcessing
'      mBmp=rbmp.rotateBitmap(bmp, -90)
'End Sub
Sub RotateImage(minHand As Bitmap, degree As Float) As Bitmap
  Dim matrix As JavaObject
  Dim bmp As JavaObject
  matrix.InitializeNewInstance("android.graphics.Matrix", Null)
  matrix.RunMethod ("postRotate", Array(degree))
  bmp.InitializeStatic("android.graphics.Bitmap")
  Dim TestImage As Bitmap = bmp.RunMethod("createBitmap", Array(minHand, 0, 0, minHand.Width, minHand.Height, _
    matrix, True))
  Return TestImage
End Sub
 
Upvote 0

aggelos

Member
Licensed User
Longtime User
For the next guy who comes across the rotateimage

if you get the error, 'as' expected
Try changing the lines
B4X:
matrix.RunMethod ("postRotate", Array(degree))
to
matrix.RunMethod ("postRotate", Array as Object(degree))

and

Dim TestImage AsBitmap = bmp.RunMethod("createBitmap", Array(minHand, 0, 0, minHand.Width, minHand.Height, _matrix, True))
to
Dim TestImage AsBitmap = bmp.RunMethod("createBitmap", Array as Object(minHand, 0, 0, minHand.Width, minHand.Height, _matrix, True))
 
Upvote 0
Top