Android Question Help displaying pictures/documents

MrKim

Well-Known Member
Licensed User
Longtime User
I need a little help loading and displaying pictures and documents. It APPEARS the best way to do this is a Webview control because I want the users to be able to use gestures to zoom/resize. But I am not married to a Webview if there is a better way. I know virtually nothing about HTML and don't really want to learn any more about it than I have to to do the job.

I found the following snippet of code,

B4X:
WebView1.LoadHtml("<html><head><style Type=""text/css""> img { position: absolute; width: 300px; height: 300px; left: 50%; top: 50%; margin-left: -150px; margin-top: -150px; }</style> </head> <body> <img src=""File:///android_asset/picture.png""> </body> </html>")

which I modified and works - loads the pictures OK.

B4X:
    WebView1.LoadHtml("<html><head><style Type=""text/css""> img { position: absolute; width: 100%; height: 100%; left: 0%; top: 0%; margin-left: -150px; margin-top: -150px; }</style> </head> <body> <img src=""" & Main.PartPicFile & """> </body> </html>")

BUT, not to scale. I know in some Windows controls there is a setting that will simply load a picture, to scale, as large as possible in a given control and leave whitespace on the top/bottom or sides if the controls scale does not match the bitmap scale. That would be ideal.

Barring that, I have already written code to load a bitmap and use the height and width property to properly size an Imageview. I could do that as well, but I need to know what part of that HTML code to change to do this :eek:.

Also, with the code above there is a 'quirk' when using gestures to resize. When I use two fingers to enlarge the image it works fine until I take my fingers off the screen, then it snaps back to size, and places the upper left corner of the image more or less randomly, sometimes completely off the screen. I need to be able to zoom in on portions of the picture (many of these images are technical drawings).

I will also need to do something similar with .pdf files, and, hopefully Word Docs and Excel files maybe even .dxf (cad drawings) I understand those will be handled by external apps but if anyone has any ideas/experience along those lines (which programs to use how, to load my files to them from my program, etc.) it would be greatly appreciated.

A little background: We have a lot of customers who use our manufacturing management software. They have spent thousands of hours writing mfg. instructions. Usually in Adobe, Word, and Excel plus a lot of pictures. The are not going to rewrite these and we want to start displaying them on tablets.

Thanks in advance for your support and thanks to everyone out there for your incredible support so far. This is truly an amazing community!
 
Last edited:

MrKim

Well-Known Member
Licensed User
Longtime User

Erel,
Thanks for the reply, after writing this I started messing around on my own. I tried Webview and found it behaved strangely. When I used pinch and zoom Webview would double up the image and jump around. I will take a look at 123572. I have actually just about completed a class that will do what I want but it has one issue yet and perhaps 123572 has resolved those. The problem is I want to both move (single touch) and size (pinch/multi-touch) an image and when I release the multi-touch if not done perfectly it sees the finger that is left as a single touch and moves the image.
Kim
 
Upvote 0

MrKim

Well-Known Member
Licensed User
Longtime User
OK! After much messing around (I am really having fun learning all of this new stuff!) I have created a class that does what I want.
I needed two things:
1. Load the image as large as possible into my view and still maintain the aspect ratio.
2. Be able to resize and move the image around to clearly view portions of the image.
(We have manufacturing clients who want to go paperless. They will be viewing detailed drawings with manufacturing specs., dimensions, etc.)

I have attached the source for a little program that loads 3 different drawings (2 look the same but one is actually horizontal and the other vertical NOT rotated.) Although I am using tablets I just left this small with the default 320x480 layout.

Here is the source for the class. Note that it requires agrahams wonderful Gestures lib. As I am new to this I have no idea if I have done this in the cleanest or most efficient manner so I would welcome any comments on the code.
Particularly - is a panel the right choice for this? I just maid an assumption that a panel is the leanest view.
I have invalidated an activity rectangle twice in one routine. Should I do that or is it more efficient to invalidate the ENTIRE Activity once? I am guessing it may depend more on how big the rectangle is relative to the activity?

B4X:
'Class module
Sub Class_Globals
    Dim Gest As Gestures
    Dim LNStart As Int
    Dim Cnv As Canvas
    Dim Rect, PnlRect  As Rect
    Dim CB As Bitmap
    Dim IBH, IBW As Float
    Dim LastX, LastY, LastLen As Float
    Dim PnlColor As Long
    Dim Act As Activity
    Dim WasMulti As  Boolean
End Sub
 
Public Sub Initialize(Bmp As Bitmap, Pnl As Panel, C As Int, A As Activity)
    Dim bmpAsp As Float, pnlAsp As Float
    CB = Bmp
    PnlColor = C
    Act = A
    PnlRect.Initialize(Pnl.left, Pnl.Top,Pnl.Left + Pnl.Width, Pnl.Top + Pnl.Height)
    Gest.SetOnTouchListener(Pnl, "pnl_gesture")
    pnlAsp = Pnl.Width / Pnl.Height
    bmpAsp = CB.Width / CB.Height
    If bmpAsp >= pnlAsp Then
        IBH = (Pnl.Width / bmpAsp)
        IBW = Pnl.Width
        Rect.Initialize(0, (Pnl.Height-IBH)/2, Pnl.Width, IBH + ((Pnl.Height-IBH)/2))      
    Else
        IBH=Pnl.Height
        IBW=(Pnl.Height * bmpAsp)
        Rect.Initialize((Pnl.Width-IBW)/2, 0, IBW + ((Pnl.Width-IBW)/2), Pnl.Height)
    End If
    Cnv.Initialize(Pnl)
    Cnv.DrawBitmap(CB, Null,Rect)
  
 
End Sub
 
Sub ResizeBmp(Amt As Float)
 
    Cnv.DrawColor(PnlColor)
    Act.Invalidate2(PnlRect)
    Rect.Initialize(Rect.Left, Rect.Top,Rect.Left + (IBW * Amt), Rect.Top + (IBH * Amt))
    Cnv.DrawBitmap(CB,Null,Rect)
    Act.Invalidate2(Rect)
    'Act.Invalidate
 
End Sub
 
Sub MoveBmp(L As Float, T As Float)
    Cnv.DrawColor(PnlColor)
    Act.Invalidate2(PnlRect)
    Rect.Initialize(L, T, L + IBW, T + IBH)
    Cnv.DrawBitmap(CB, Null, Rect)
    Act.Invalidate2(Rect)
End Sub
 
Sub pnl_gesture(o As Object, ptrID As Int, action As Int, X As Float, y As Float) As Boolean
Dim LN As Int, X0,X1,Y0,Y1 As Float  ', a As String, v As Panel
Dim Amt As Float
    Select action
        Case Gest.ACTION_DOWN
            LNStart = 0
            LastX = X - Rect.Left: LastY=y - Rect.Top
        Case Gest.ACTION_MOVE
            If Gest.GetPointerCount = 2 Then
                X0 = Gest.GetX(Gest.GetPointerID(0)): Y0 = Gest.Gety(Gest.GetPointerID(0))
                X1 = Gest.GetX(Gest.GetPointerID(1)): Y1 = Gest.Gety(Gest.GetPointerID(1))
                LN = Sqrt(((X0-X1)*(X0-X1))+((Y0-Y1)*(Y0-Y1)))
                If LNStart = 0 Then LNStart = LN
                If LastLen <> 0 Then ResizeBmp(LN/LNStart)
                LastLen = LN
                WasMulti = True
            Else If Gest.GetPointerCount = 1 Then
                If Not(WasMulti) Then
                    If LastX + LastY <> 0 Then
                        MoveBmp((X - LastX), (y - LastY))
                    End If
                End If
            End If
    End Select  
    If action = Gest.ACTION_UP Then
        IBW = Rect.Right-Rect.Left
        IBH = Rect.Bottom-Rect.Top
        LastX = 0: LastY = 0
        LastLen = 0
        WasMulti=False
    End If
  
    Return True ' need to return true otherwise we don't get any other events in the gesture
End Sub

And here is the main module it relies on the View Main which is simply three panels.
B4X:
Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.
    Dim Panel1, Panel2, Panel3 As Panel, EditText1 As EditText
End Sub
 
Sub Activity_Create(FirstTime As Boolean)
    Dim I1, I2, I3 As ImageView2, b As Bitmap
 
    If Not(File.Exists(File.DirInternal,("testpart.jpg"))) Then
        File.Copy(File.DirAssets,("testpart.jpg"),File.DirInternal,("testpart.jpg"))
        File.Copy(File.DirAssets,("testpart2.jpg"),File.DirInternal,("testpart2.jpg"))
        File.Copy(File.DirAssets,("testpart3.jpg"),File.DirInternal,("testpart3.jpg"))
    End If
 
    Activity.LoadLayout("Main")
    Panel1.Color = Colors.LightGray
    Panel2.Color = Colors.LightGray
    Panel3.Color = Colors.LightGray
    Activity.Initialize("")
    b=LoadBitmap(File.DirInternal,("testpart.jpg"))
    I1.Initialize(b, Panel1, Colors.LightGray, Activity)
    b=LoadBitmap(File.DirInternal,("testpart2.jpg"))
    I2.Initialize(b, Panel2, Colors.LightGray, Activity)
    b=LoadBitmap(File.DirInternal,("testpart3.jpg"))
    I3.Initialize(b, Panel3, Colors.LightGray, Activity)
  
End Sub

I this seems like useful code I will post it separately so it is easier to find.

Kim
 

Attachments

  • ImageView2.zip
    65.9 KB · Views: 344
Upvote 0

MrKim

Well-Known Member
Licensed User
Longtime User
As to the other part of my query, I have resolved that as well. Google provides QuickOffice for free, and it seems to display .pdf, .xls, and .doc files beautifully. Again, being new to this it took me awhile to figure out two things:
1. How to set up the path in the intent.
2. What exactly was the intent Type.

The path particularly seems non-intuitive as it seems to require THREE (///) forward slashes by the time all is said and done (File.DirDefaultExternal comes with 1 / already).

Here is the code I am using to successfully open these three types of files with QuickOffice. The WrapAsIntentChooser never did anything. Don't know why.

B4X:
Sub OpenPdf_Click
Dim i As Intent 'Requires a reference to the Phone library
 
    i.Initialize(i.ACTION_VIEW, "file://" &  File.DirDefaultExternal & "/713-042124-001.pdf")
    i.SetType("application/pdf")
    'i.WrapAsIntentChooser("Choose PDF Viewer")
    StartActivity(i)
 
End Sub
Sub OpenExcel_Click
Dim i As Intent 'Requires a reference to the Phone library
 
    i.Initialize(i.ACTION_VIEW, "file://" &  File.DirDefaultExternal & "/0267337-001_BOM-NPI-Import.xls")
    i.SetType("application/vnd.ms-excel")
    'i.WrapAsIntentChooser("Choose Excel Viewer")
    StartActivity(i)
  
End Sub
 
Sub OpenWord_Click
Dim i As Intent 'Requires a reference to the Phone library
 
    i.Initialize(i.ACTION_VIEW,  "file://" & File.DirDefaultExternal & "/Test.doc")
    i.SetType("application/vnd.ms-word")
    'i.WrapAsIntentChooser("Choose Word Viewer")
    StartActivity(i)
  
End Sub
 
Upvote 0
Top