Confused about Pictures, Graphics & Canvas

I am not sure.

You start with a 50 x 200 @ 144dpi image (suffixed @2x), then reduce its dpi to 72dpi, save it and use both AFAIK.

The canvas is set to hold a 50 x 200 picture: reducing to 72dpi the 50x200 @ 144dpi pct, it becomes 25x100; that’s why I reduced to 72dpi the 100x400 @ 144dpi.
So, now I have two pictures:
50x200 @ 72
100x400 @ 144 (to fill the @2x slot)

My head is spinning…

[quote]50x200 @ 72
100x400 @ 144[/quote]
This is correct. I think you’re missing the distinction between points and pixels. When you say “The canvas is set to hold a 50 x 200 picture”, that’s 50 x 200 points. The dpi scales the number of pixels to number of points as: points = pixels * 72 / dpi. So 50x200 pixels @ 72 becomes 50x200 points and 100x400 pixels @ 144 becomes 50x200 points also. If the pixel size and dpi are correct you should be able to just put them in an Image Set and the rest works.

Will beat me and explain far better than what I wrote. Unfortunately, the concept is not easy.

Before Retina (HiDPI), the screen resolution in dpi was 72. Now it can be far from that.

An image application is able to display all pixels of an image OR all points of the same image. When the image is 72 dpi, the size on screen of the display (as either all pixels or all points) shows the same “screen size”.

The situation will be different when the image is 144dpi (for example) asking the image application to display all pixels or all points is a different matter.

Back to your question: to keep quality, you have to create the lowest quality image (the one at 72 dpi) from the other image (the one at 144 dpi).

Nota: in Apple’s Preview, when you Copy / Paste an image, in El Capitan and prior (I do not tested macOS Sierra), the dpi is lost in the process. That does not help you to understand the process.

Last: to avoid loosing the image original dpi, use cmd-shift-s (in Preview) or duplicate the image file on disk and load the copy / apply the changes.

In old Photoshop, the preferences choice was: display all pixels (or something like that) to display… all pixels: in that case, a 50 x 200 @144dpi will be displayed as if it is a 100 x 400 image on screen.

On short: remember that the important stuff is the higher dpi image and always create the 72 dpi image FROM the 144dpi image.

Did you see the Picture image set feature in Xojo 2016r3 ?

Carlo:

Download the image here .

Make two copies of the original file.

Append " - 600 @ 72dpi" to the first file (remove “copy”), then " - 600 @ 144dpi" to the second copy.

In Preview:
Load the first image, then resize it to 600 pixels tall, save it.
Load the second image, then resize it to 600 pixels tall, set the dpi to 144 and save it.

If everything is OK, one file will be 193KB (72 dpi), the other 500KB (144dpi).

The size displayed in the Finder (in blue, below the file name is the same for both files; the difference is in the dpi value (and foot print [size in disk]).

I hope this is clear now.

I think I got the matter clearer than before. Never too late to learn.
Thank you, Will and Emile.

[quote=59555:@Tim Hare]A Canvas does not store what is drawn on it. I think that’s where you’re getting confused. It sounds like you expect the Backdrop to contain the contents of the canvas. It doesn’t. It’s a quick and dirty way of getting a fixed image to display on the canvas. Consider it a one-way street.

If you want the “contents” of the canvas, there are a couple of ways to approach it.

  1. Draw everything to a buffer Picture object and then draw the picture to the canvas. best
  2. Use DrawInto to cause the Canvas Paint event to fire. (may or may not actually work, you may have to DrawInto the entire window and extract the area that the canvas occupies)
  3. Take a screen shot and extract the area that the canvas occupies.[/quote]

May I have a sample for option number one? I’ve a canvas with a xojo standard report where i paint on some pictures in paint event of the canvas and they are not printed as output

Because the paint is “volatile”.

Paint that image in a Picture Object that you draw “permanently” in the Paint event.

Dim OffscreenPict As New Picture(200,200) // draw your image in OffscreenPict

In the Paint event:

If OffscreenPict <> Nil Then // your OffscreenPict here End If

[quote=354442:@Emile Schwarz]Because the paint is “volatile”.

Paint that image in a Picture Object that you draw “permanently” in the Paint event.

Dim OffscreenPict As New Picture(200,200) // draw your image in OffscreenPict

In the Paint event:

If OffscreenPict <> Nil Then // your OffscreenPict here End If[/quote]

I need to print on the printer the whole image … its a xojo report with optional dynamic images loaded on.

Code ?

In canvas paint event

//load the report OK

If mReportDocument <> Nil Then

g.DrawPicture(mReportDocument.Page(paginacorrente), 0, 0)

end if

//conditional (boolean field) load of the little brown image OK
// teamRecordSet comes from a database SELECT statement

  if teamrecordset.Field("arachidi").BooleanValue then
    
    dim f as folderitem = GetFolderItem(app.AppImageDirectory.AbsolutePath + "arachidi.png")
    dim p as picture = f.OpenAsPicture
    Dim scale As Double = 0.30
    
    g.DrawPicture(p, 430, 320, p.Width * scale, p.Height * scale, 0, 0, p.Width, p.Height)
    
  end if

//print code the little brown image is not printed :frowning:

Dim ps As New PrinterSetup

If ps.PageSetupDialog Then

ps.MaxHorizontalResolution = 1200
ps.MaxVerticalResolution = 1200

Dim g As Graphics
g = OpenPrinterDialog(ps)
If g <> Nil Then
’ Print the report
rpt.Document.Print(g)
End If
End If

Please may you write me a correct code solution?

I never use reports, so I cannot tell you if this will work, but:

When you call rpt.document.print(g) it simply sends each page at a time to the printer.
There is no paint event you can draw your little brown picture in, and it is not part of the pages that are sent.

You can TRY amending the page before you call print.
If the page() array is read-only, it will fail.
If the page() array is regenerated when you call print, it will not produce the brown image

but you can try:

[code]mReportDocument.Page(paginacorrente),graphics.drawpicture p, 430, 320, p.Width * scale, p.Height * scale, 0, 0, p.Width, p.Height)

//and then

rpt.document.print(g)[/code]

If that doesnt work, you can save the pages as images into a temporary folder, amend the page you want, and then print the pages yourself.

Or you can print to a PDF file and amend the relevant page if you have the DynaPDFMBS plugins.

[quote=354464:@Jeff Tullin]I never use reports, so I cannot tell you if this will work, but:

When you call rpt.document.print(g) it simply sends each page at a time to the printer.
There is no paint event you can draw your little brown picture in, and it is not part of the pages that are sent.

You can TRY amending the page before you call print.
If the page() array is read-only, it will fail.
If the page() array is regenerated when you call print, it will not produce the brown image

but you can try:

[code]mReportDocument.Page(paginacorrente),graphics.drawpicture p, 430, 320, p.Width * scale, p.Height * scale, 0, 0, p.Width, p.Height)

//and then

rpt.document.print(g)[/code]

If that doesnt work, you can save the pages as images into a temporary folder, amend the page you want, and then print the pages yourself.

Or you can print to a PDF file and amend the relevant page if you have the DynaPDFMBS plugins.[/quote]

Hi Jeff your code did’nt work but you 've opened my mind and i found a working solution! Thank you!


'On print command


Dim ps As New PrinterSetup

If ps.PageSetupDialog Then
  
  ps.MaxHorizontalResolution = -1
  ps.MaxVerticalResolution = -1
  
  Dim g As Graphics
  g = OpenPrinterDialog(ps)
  If g <> Nil Then
    ' Print the report
    
//new picture a4 on the fly
    Dim p As New Picture(595, 842)
    
    //main report
    p.Graphics.DrawPicture(mReportDocument.Page(1), 0, 0)
    
    dim f as folderitem = GetFolderItem(app.AppImageDirectory.AbsolutePath + "arachidi.png")
    dim s as picture = f.OpenAsPicture
    Dim scale As Double = 0.30
    
    p.Graphics.DrawPicture(s, 430, 320, p.Width * scale, p.Height * scale, 0, 0, p.Width, p.Height)
    
   
// works!!!
 g.DrawPicture(p,0, 0)
    
   
  End If
End If

Please use the code tags when you add source code to your reply.
Press the page icon with the < > symbols on it, or use [ code ][ /code ]
(Remove the space after [ and before ])
Using code tags makes your code much more readable.