Android Question ImageView Bitmap centered

LucaMs

Expert
Licensed User
I don't know the right definition...
I use a Tool in wich it is named "Streched proportional".

I have not been able to get this "simple" thing:
upload_2014-8-12_15-0-12.png



(boxes represent some ImageView. On the right the two loaded files)

I tried with "normal" code, and also using the Informatix's BetterImageView library.

I post one of the 100 attempts.
B4X:
Sub FitCenterBitmap(Imv As ImageView, Dir As String, FileName As String)
    Imv.Gravity = Gravity.CENTER

    Private bmp As Bitmap = LoadBitmap(Dir, FileName)
    Private NewBmp As Bitmap
    Private NewBmpWidth, NewBmpHeight As Int

    Private ImvBmpWRatio, ImvBmpHRatio As Float
    Private ScaleFactor As Float

    ImvBmpWRatio = Imv.Width / bmp.Width
    ImvBmpHRatio = Imv.Height / bmp.Height

    If ImvBmpWRatio < ImvBmpHRatio Then
        ScaleFactor = ImvBmpWRatio
    Else
        ScaleFactor = ImvBmpHRatio
    End If

    NewBmpWidth = bmp.Width * ScaleFactor
    NewBmpHeight = bmp.Height * ScaleFactor

    NewBmp = CreateScaledBitmap(bmp, NewBmpWidth, NewBmpHeight)
    Imv.Bitmap = NewBmp
End Sub

(I already know that the great Klaus will make me feel ashamed, solving it in two minutes :D)


[P.S. I would prefer even better quality/definition, of course]



Now there are at least two Klaus (Klaus Matle and ... Klaus).

I like to call Klaus: the "great Klaus", but Matle may not be small :), so we could call the first one: "fully Klaus" :) - see his profile.
 
Last edited:

klaus

Expert
Licensed User
I would do it that way:

EDIT: 2019.12.05

The routine FitCenterBitmap below can simply be replaced by this:
B4X:
ImageView1.Bitmap = LoadBitmapResize(Dir, FileName, Imv.Width, Imv.Height, True)
ImageView1.Gravity = Gravity.CENTER
The routine below was written before the LoadBitmapResize method did exist.


Old routine.
B4X:
Sub FitCenterBitmap(Imv As ImageView, Dir As String, FileName As String)
    Private bmp As Bitmap = LoadBitmap(Dir, FileName)
    Private cvs As Canvas
    cvs.Initialize(Imv)
 
    Dim rectDest As Rect
    Dim delta As Int
    If bmp.Width / bmp.Height > Imv.Width / Imv.Height Then
        delta = (Imv.Height - bmp.Height / bmp.Width * Imv.Width) / 2
        rectDest.Initialize(0, delta,Imv.Width, Imv.Height - delta)
    Else
        delta = (Imv.Width - bmp.Width / bmp.Height * Imv.Height) / 2
        rectDest.Initialize(delta, 0, Imv.Width - delta, Imv.Height)
    End If
    cvs.DrawBitmap(bmp, Null, rectDest)
    Imv.Invalidate
End Sub
 
Last edited:

sorex

Expert
Licensed User
maybe a stupid question but...

why don't you just reposition the imageview after it's been rescaled/drawn to?

having an imageview larger than your image just eats away memory for nothing.
 

LucaMs

Expert
Licensed User
Because I resize them at the start but then I need to load different images at runtime within them (more specifically, each player will load his image in a fixed place - ImageView)
 

LucaMs

Expert
Licensed User
the ImageView is inside a customview.
I'dont understand what you mean.

I will have x players sitting around a table.
Each player will have its own predefined space (adapted only at the beginning, thanks to the module Scale ;)) which is just a CustomView (imageview and a couple of panels containing other views).

The player will enter "bringing" their own image ("Avatar"?), which may have a different size/dimensions/ratio (within certain size limits, otherwise the resizing will result in a poor quality).

I think that the solution is the one that you have brilliantly solved
 

klaus

Expert
Licensed User
the ImageView is inside a customview.
This is new in this thread !

What kind of CustomView ?
Is it yours ?
If yes, how do you add the image to the CustomView ?
You could define an area for the ImageView in your CustomView and according to the dimensions of the bitmap resize the ImageView according to the bitmap and recenter horizontally or vertically the ImageView similar to what I showed in the example in post #2 in the area you defined for the ImageView.
 
Last edited:

LucaMs

Expert
Licensed User
It is a my customview, but you should think to it as a block, not as a view to be reused in other projects, unless they are of the same kind.

I simpy pass a bitmap to a property in the customview class, then I use your FitCenterBitmap to fit the bitmap into the imageview.

I can't see the problem, it works well.

I also managed to get the convenience of loading a layout in CustomView and the CustomView is with Designer support.

More than that I could not wish for ;)
 

klaus

Expert
Licensed User
But the pertinent ramark of sorex in post#4 still remains !
This could be avoided with my suggestion in post#10.
You define in your CustomView an area for the ImageView, so why not adjust the ImageView to this area instead of adjusting the bitmap into a fixed ImageView.
 

LucaMs

Expert
Licensed User
uhm ... I'll see if implementing this change because the final effect should be the same.

Thanks
 

sorex

Expert
Licensed User
Klaus is right, why not have 4 imageviews next to each other instead of 1 with 4 images copied to it?

don't get me wrong, as long as it works it's fine for me but the logic is kind of far away (for me) :)
 

LucaMs

Expert
Licensed User
Klaus is right, why not have 4 imageviews next to each other instead of 1 with 4 images copied to it?

don't get me wrong, as long as it works it's fine for me but the logic is kind of far away (for me) :)
4 images/ImageViews?

The "logic" is the first that I thought seeing this.
It is from Zynga Poker - web version:
upload_2014-8-13_4-36-4.png


(First of all, that's not me: i'm more rich! :D)

I immediately thought of a CustomView which contained a imageview and more.
Initially it is empty; when the player joins the table, you will see his picture and his nickname.

I think that in that game the image is partial: they probably take the central part of the photo that the user have chosen.

The yellow frame indicates the time yet available; I wonder how they get that effect (though I would not want to be accused of plagiarism, so I will do it differently)

So, each player don't need x images, althought I could resize the imageview instead of the bitmap (or cut the bitmap's "borders", as they do, I think).

But what is the advantage of changing the size of the ImageView instead of those of the bitmap, since moreover in this way now does it work?


[P.S. I now understand your question about the four images, sorex, reading the thread again. It is related to the first post, but that was just an example]
 
Last edited:

sorex

Expert
Licensed User
Mornin' Luca,

I thought you would display the 4 players next to each other with or without a gap inbetween but you don't.
It's more like you draw the entire scorepanel inside that custom view.

that time effect can be done with a path or bezier based fill based on sin/cos values based on the time just like you would draw a pie chart
the only part I don't get yet (in android) is how you could mask out the stuff that's drawn too much. (without libraries)
 

LucaMs

Expert
Licensed User
Sorry, I have not commented on your post.

It is evident that you know the graphic techniques, I do not.

Anyway, I solved with a simple progressbar beneath the photo, so I will not have technical problems (or "copyright" problems)
 

klaus

Expert
Licensed User
To adjust the ImageView you could use this routine.
B4X:
Sub AdjustImageView(Imv As ImageView, Dir As String, FileName As String)
    Private bmp As Bitmap = LoadBitmap(Dir, FileName)
 
    Dim Delta, Height, Width As Int
    If bmp.Width / bmp.Height > Imv.Width / Imv.Height Then
        Height = bmp.Height / bmp.Width * Imv.Width
        Delta = (Imv.Height - Height) / 2
        Imv.Height = Height
        Imv.Top = Imv.Top + Delta
    Else
        Width = bmp.Width / bmp.Height * Imv.Height
        Delta = (Imv.Width - Width) / 2
        Imv.Width = Width
        Imv.Left = Imv.Left + Delta
    End If
    Imv.Gravity = Gravity.FILL
    Imv.Bitmap = bmp
End Sub
 
Last edited:
Top