Android Question Macroscopic difference in creating images

AlpVir

Well-Known Member
Licensed User
Longtime User
I attached 2 thumbnail PNG images created with the exact same code, a emulator and a physical device.
Unfortunately, the image created by the emulator is essentially correct and that created by the physical device is grossly incorrect.
I have no idea to explain this difference.
The original images are both of 1200x1200 pixels and each of 1442401 points is written with the statement Canvas.DrawPoint (CX, CY, Colore) in a For-Next loop.
What could I have your suggestion to solve the problem ?
Thank you for your attention.
 

Attachments

  • N44E007_emulator.png
    N44E007_emulator.png
    138.1 KB · Views: 174
  • N44E007_device.png
    N44E007_device.png
    134.5 KB · Views: 189

Mark Read

Well-Known Member
Licensed User
Longtime User
I think one of my problems may be similar. I analyse pixels on a bitmap. On the emulator I get constant results (RGB, R=181 etc) and on my galaxy tablet, I get something completely different (RGB, 170<R<190). Could this be something to do with the color resolution of the emulator and real devices?
 
Upvote 0

AlpVir

Well-Known Member
Licensed User
Longtime User
Upvote 0

Straker

Active Member
Licensed User
Longtime User
Did you just try a single physical device, or more than one? Same behavior?
Can you post the loop code (or better a piece of code and the original image so I can test it with some other devices?)
 
Upvote 0

AlpVir

Well-Known Member
Licensed User
Longtime User
I only tried on a Motorola Defy plus and on the emulator; the results are completely different.
Below I report the code of the entire For-Next loop with the statement that draws 1442401 points.
C.DrawPoint (CX, CY, Colore)
Tomorrow I will provide a link to download the entire app.
B4X:
    Dim InputStream1 As InputStream
    Dim B1 As Byte , B2 As Byte
    Dim buffer(MaxLenFile) As Byte
    InputStream1 = File.OpenInput (File.DirRootExternal,  NomeFileDEM)
    count = InputStream1.ReadBytes (buffer,0,MaxLenFile-1)
    InputStream1.Close
    
    For i=0 To MaxLenFile-1 Step 2       
        B1=buffer(i) :    B2=buffer(i+1) : H=Bit.AND(B1, 255)*256+Bit.AND(B2, 255) 
        If H < MaxAltezza Then
            lintValor = (H / MaxAltezza) * 1500  
            Reflejo = getReflexion2 (H)
            If H <= 0 Then
                R = 0: G = 0: B = 255
            Else
                If lintValor <= 250 Then
                   lauxval = lintValor
                   R = 0 / Reflejo: G = (180 + lauxval * 0.3) / Reflejo: B = lauxval / Reflejo
                Else
                   If lintValor <= 500 Then
                      lauxval = lintValor - 250
                      R = 0: G = (255 - (lauxval * 0.3)) / Reflejo: B = 250 / Reflejo
                   Else
                      If lintValor <= 750 Then
                         lauxval = lintValor - 500
                         R = (50 - lauxval * 0.15) / Reflejo: G = (180 - lauxval * 0.3) / Reflejo: B = (250 - lauxval * 0.3) / Reflejo
                      Else
                         If lintValor <= 1000 Then
                            lauxval = lintValor - 750
                            R = 12.5 / Reflejo: G = (105 - lauxval * 0.3) / Reflejo: B = (175 - lauxval * 0.3) / Reflejo
                         Else
                            If lintValor <= 1250 Then
                               lauxval = lintValor - 1000
                               R = (12.5 - lauxval * 0.01) / Reflejo: G = (30 - lauxval * 0.05) / Reflejo: B = (100 - lauxval * 0.2) / Reflejo
                            Else
                               If lintValor <= 1500 Then
                                  lauxval = lintValor - 1250
                                  R = (10 + lauxval * 0.9) / Reflejo: G = (17.5 + lauxval * 0.9) / Reflejo: B = (50 + lauxval * 0.8) / Reflejo
                               End If
                            End If
                         End If
                      End If
                   End If
                End If
            End If
            R=R Mod 256
            G=G Mod 256
            B=B Mod 256
            ColoreX = Colors.RGB (B,G,R)  ' OK (B,G,R)
            C.DrawPoint (CX,CY,ColoreX)
            CX = CX + 1
            If CX>MaxDem Then  CY=CY+1:CX=0
        End If
        prog.Progress = i / lung * 200
        If i Mod 100=0 Then DoEvents
    Next
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
Sì, le immagini avranno anche le medesime risoluzioni, ma anche i display?
E non impiega un anno e mezzo per la visualizzazione?


Yes, the images have the same resolutions, but also the display?
Takes it a year and a half for the display?
 
Upvote 0

AlpVir

Well-Known Member
Licensed User
Longtime User
To reproduce the problem:
1) download the file N44E007.hgt (http://www.fiab.info/bicitalia/srtm/dem/N44E007.hgt) 2.8 MB
2) copy it to the folder of the SD card DEM/3 (DEM/3/N44E007.hgt)
3) launch the app attached.
Execution times :
- emulator in real mode 112 seconds
- physical device: 32 seconds
If the displays have different resolution, this should lead to a "resize" of the generated image, not to a "distortion." Or not?
Thanks in advance
 

Attachments

  • LeggiDEM.apk
    132.5 KB · Views: 97
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
If I'm not mistaken, all the code works on the colors.
cx and cy should instead be adapted to the size of your screen.
 
Upvote 0

AlpVir

Well-Known Member
Licensed User
Longtime User
@LucaMs
Right.
But it does not explain the macroscopic difference image produced by emulator and physical device.
In any case, I do not care a correct image on the emulator (which I managed to create), but a correct image on the physical device !
Even if you change the statment
C.DrawPoint (CX, CY, ColoreX)
in
C.DrawPoint (DipToCurrent(CX), DipToCurrent(CY), ColoreX)
the result does not change.
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
There is a difference because most likely emulator and device have different resolutions.

No, DipToCurrent is not enough, you will need to make relations between the width and height of the target screen (target layout) and those of the image.

Now comes Klaus and will do it in 2 minutes :)
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
In practice, the question is what kind of relationship you choose between (ImageWidth/ScreenWidth) and (ImageHeight/ScreenHeight) so that the image can fit completely on the screen and then multiply cx and cy by that factor.

(some one told (wrote) me: ""Give a man a fish, he'll eat for a day; teach him how to fish, and he'll eat for a lifetime." (Klaus :)))
 
Upvote 0

AlpVir

Well-Known Member
Licensed User
Longtime User
I am not convinced that this is a problem of resolution of the screens.
If this were just multiply or add a certain amount to the coordinates X and Y. This would only serve to "magnify" or "translate" the image, not distort it.

Non sono convinto che si tratti di un problema di risoluzione degli schermi.
Se così fosse basterebbe moltiplicare o aggiungere una certa quantità alle coordinate. Questo non farebbe altro che "ingigantire" (primo caso) o "translare" (secondo caso) l'immagine, non distorcerla.
Ho fatto numerose prove in proposito, moltiplicando o aggiungendo qualcosa ad una coordinata, all'altra, ad entrambe. Nulla !
 
Last edited:
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
Sorry, my english is not so good :(

Certo che in italiano mi riesce più facile :)

Si, il problema è quello: se l'immagine è 1200x1200 non puoi ottenerla identica, con le stesse coordinate, su uno schermo 320x480, no?
In questo caso, dato che il minimo è 320, tu avrai 320/1200 = 0.2666666666. Moltiplicando questo valore per cx e cy, otterrai una immagine sempre quadrata di 320x320 ma esattamente uguale.


Yes, that is the problem: if the image is 1200x1200 you can not get the same, using the same coordinates, on a 320x480 screen, no?
In this case, given that the minimum is 320, you will be 320/1200 = 0.2666666666. Multiplying this value for cx and cy, you get a square image of 320x320 but exactly the same.
 
Last edited:
Upvote 0

Straker

Active Member
Licensed User
Longtime User
Just to cut any resolution problem, I suggest to sligtly change the code and check the CX and CY variables.
Lets say IF (CX<200) AND (CY<200) THEN C.DRAWPOINT....

This way you will plot just the first angle (200x200px) of your image. If this portion is correct on both screen, then Luca is correct and we'll have to found out how overcome this issue. If also the portion is distorced, then Luca is wrong (as always:D).

Sorry, I cannot test what I said now (hopefully in the afternoon)
 
Upvote 0

AlpVir

Well-Known Member
Licensed User
Longtime User
IF (CX <200) AND (CY <200) THEN C.DRAWPOINT ....

Interesting suggestion, but ... no positive result. The image is always "distorted" and unrecognizable.
Before For-Next loop I have this statement

B4X:
bmp.InitializeMutable(MaxDem,MaxDem)
    C.Initialize2 (bmp)

and after
B4X:
Dim out As OutputStream
    out = File.OpenOutput(File.DirRootExternal ,NomeFilePNG,False)
    bmp.WriteToStream (out,100,"PNG")
    out.Close
These could be held responsible for the malfunction?
 
Upvote 0

AlpVir

Well-Known Member
Licensed User
Longtime User
I apologize for my English. I hope I make myself understood
I've tried everything:
- Write a JPG instead of PNG
- Multiply and / or divide CX and / or CY for a series of constants (0.5, 1.333, 1/1201, etc.).
- Define CX and CY as variables LONG instead of INT
- The same but just considering or CX or CY
- Add some DoEvents
- I verified that the image directly on the smartphone was actually "messed up" and was not responsible for the procedure for viewing (ie TouchImageView)
- Writing
C.DrawPoint (1200-CX, 1200-CY, ColoreX)
instead of
C.DrawPoint (CX, CY, ColoreX)
- At the end of the writing of the points I put 2 instructions that draw a cross.
C.DrawLine (0,0, MaxDem-1, MaxDem-1, Colors.Red, 1dip)
C.DrawLine (1,0,0-MaxDem, MaxDem-1, Colors.Blue, 1dip)
The two lines are perfect and combine the 4 corners of the square.

What else do you think ?
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
Can you post your project?

Probably I will not be able to use it, because I have not a very recent version of B4A, but someone will be able to solve your problem.
 
Upvote 0

Straker

Active Member
Licensed User
Longtime User
I'll try your app in a couple of hours, with 2or 3 devices, so we'll see what's happening.
In the meantime, can you explain a little bit of your code?

I think that is a classic Endian problem.
If you can see, in your code if NOT H<MaxAltezza you 'skip' the pixel. If what I think is right, can you please move cx=cx+1 and the next if cx... line OUTSIDE the Main if (place them just before the next, just to be sure they are always executed)
 
Upvote 0
Top