[Rsolu] Export du contenu d'un Canvas au format png, jpeg,...

Bonjour,

je souhaiterai exporter le contenu d’un Canvas sous forme de fichier JPEG ou PNG. Le nom du Canvas est Affichage. J’ai parcouru le forum et essay diverses solutions proposes A chaque fois, f.exists =false

Ceci semble normal d’aprs le Langage de Rfrence : “The GetSaveFolderItem function does not create the file. It simply returns a FolderItem that represents the potential file. To create the actual file, you will need to call or Create shared method for TextOutputStream or the Create shared method of the BinaryStream.”


// ----------------------------------------//
// sauvegarde des courbes au format png //
// ----------------------------------------//

Dim jpegType As New FileType
jpegType.Name = “image/jpeg”
jpegType.MacType = “JPEG”
jpegType.MacCreator = “prvw”
jpegType.Extensions = “jpg;jpeg”

Dim pngType As New FileType
pngType.Name = “image/png”
pngType.MacType = "PNG "
pngType.MacCreator = “ogle”
pngType.Extensions = “png”

Dim f As FolderItem
dim g as graphics
//using the addition and conversion operators…

f = GetSaveFolderItem( jpegType + pngType,"" ) // une solution plus simple f = GetSaveFolderItem(“image/png”,"") et suppression de tout le bloc de dclaration

If f.Exists then
//file saved
dim imp as new Picture( Affichage.Width, Affichage.Height, 32)
Affichage.DrawInto imp.Graphics, 0, 0

dim gheight as Integer = g.Width/imp.Width*imp.Height
imp.Save(f,imp.SaveAsPng)

Else
MsgBox(“le fichier n’existe pas”)
End if


le seul exemple qui “fonctionne” est le suivant :

// ----------------------------------------//
// sauvegarde des courbes au format png //
// ----------------------------------------//

Dim f As FolderItem
dim g as graphics
dim pagesetup as new PrinterSetup

g = openPrinterDialog(pageSetup,Fenetre) // Fenetre est le nom de la fentre contenant le Canvas

if g<>nil then
dim imp as new Picture( Affichage.Width, Affichage.Height, 32)
Affichage.DrawInto imp.Graphics, 0, 0
dim gheight as Integer = g.Width/imp.Width*imp.Height

g.DrawPicture imp, 0, 0, g.Width, gheight, 0, 0, imp.Width, imp.Height

end if

J’obtiens un menu popup qui me permet d’enregistrer au format PDF, et de l, je peux convertir le PDF en n’importe quoi. Convivial n’est-il pas ?

Auriez-vous une solution ?

Merci

Bonjour,

je ne sais pas d’où vient cette idée d’utiliser DrawInto pour enrregistrer le contenu d’un Canvas…

Bon, as-tu lu ces pages ?
Picture
Picture.Save

Enfin, ce code le fait (ici, vérifié):

[code] Dim DesktopFI As FolderItem
Dim SaveFI AS FolderItem

// Check if there is an image to be saved from the Canvas
If cPhoto.Backdrop = Nil Then
MsgBox “There is no image to be saved…”

// In case of trouble stop here
Return

End If

// Set the destination folder to be the Desktop
DesktopFI = SpecialFolder.Desktop
If DesktopFI = Nil Then
MsgBox “Unable to write into the Desktop folder.”

// In case of trouble stop here
Return

End If

// Get a reference for the Picture
SaveFI = DesktopFI.Child(“Image from Canvas.png”)
If SaveFI = Nil Then
MsgBox “Unable to save the image.”

// In case of trouble stop here
Return

End If

// Save the image out to the file
cPhoto.Backdrop.Save(SaveFI, Picture.SaveAsPNG)[/code]

Tu peux remplacer SpecialFolder par SaveAsDialog pour aisser lutilisateur le choix du nom du fichier et son emplacement.

Maintenant, si tu veux gnrer un PDF (mettre ton ilmage dans un PDF tel que tu le dcris), cest une autre histoire.

Pour cel tu dois imprimer cette image.

Lis la page PrinterSetup .

Dans le deuxime exemple, remplace la ligne g.DrawString("Hello World", 50, 50) par g.DrawPicture MonCanvas,0,0

Bonjour,

merci pour ta rponse. Pour rpondre ta question

cette ide m’est venue d’'une rponse une question similaire que j’ai trouve quelque part sur ce forum, (mais en version anglaise) et qui semblait rpondre ma question. Mon programme va, entre autre, tracer des courbes. Je les trace dans un Affichage.
J’avoue ne pas comprendre toutes les subtilits de Canvas, mais dans mon cas, il me semblait pertinent de transfrer le contenu de Affichage dans une Picture, un “Exdrop” en quelque sorte.

Quoi qu’il en soit, en analysant plus profondment mon code, je me suis aperu que le bug n’tait pas l o je le pensais, mais quel’erreur NilObjectExceptionError concernait l’objet “g” (graphics), que finalement je n’utilise pas vraiment.

le code suivant fonctionne comme je le souhaite Il m’a t propos, en trs grande partie, dans les rponses mon post dans la partie General, en anglais, de ce forum (la patience ne vient pas avec l’ge)

[i]dim fSave as FolderItem = GetSaveFolderItem( “image/png”,“” )

dim imp as new Picture( Affichage.Width, Affichage.Height, 32)

// si fSave is nil, c’est que l’utilisateur a tap “Esc” ou “Annnule”
if fSave = nil then return

if fSave.Exists = true then
fSave.Delete

if fSave.LastErrorCode <> 0 then
// Une autre erreur s’est produite
MsgBox(“Fichier inexistant”)
Quit

end
end

Affichage.DrawInto imp.Graphics, 0, 0

imp.Save(fsave,imp.SaveAsPng)[/i]

Ton code n’est pas clair…

Que fait donc là cette ligne:

Si tu dessine dans un Picture et assigne ce Picture à ton Affiche.Backdrop (le Canvas), tu peux enregistrer directement ton Picture, tu peut l’imprimer à partir de là…
C’est peut être ce que fait dans le désordre ton objet imp ?

Aussi, si je ne me trompe pas, Quit dans un programme fait… quitter l’application.

As-tu regardé ce que fait la commande DrawInto ?

Est-tu nouveau sur Xojo ?

As-tu regardé les exemples situés dans le dossier Graphics and Multimedia ?

Pas rellement (RealBasic V1.0 ->V4), mais trs nouveau dans beaucoup de domaines dont je n’avais pas encore l’utilit , et comme chaque version s’enrichit de nouvelles fonctions, ou modifie lgrement l’usage d’une fonction

[quote]Si tu dessine dans un Picture et assigne ce Picture ton Affiche.Backdrop (le Canvas), tu peux enregistrer directement ton Picture, tu peut limprimer partir de l
Cest peut tre ce que fait dans le dsordre ton objet imp ?[/quote]

Je suis dans une de mes zones d’ignorance. J’ai repomp un code qui semblait fonctionner :

https://forum.xojo.com/45443-resolu-export-du-contenu-d-un-canvas-au-format-png-jpeg/0/

[i]Eli Ott is not verified 5 Mar 2014 Europe (Berlin, Germany)
Edited 4 years ago

Canvas.BackDrop is a Picture which you assign as background - hence the name “Back…”. In the paint event you draw in front of the BackDrop.

To save the content of the Canvas use DrawInto like this:

Dim pic As New Picture(MyCanvas.Width, MyCanvas.Height, 32)
MyCanvas.DrawInto(pic.Graphics, 0, 0)
pic.Save(oFolder, Picture.SaveAsPNG)[/i]

Tout fait, pour le moment il s’agit d’une gestion plus que simpliste des erreurs, que je travaillerai plus tard

Oui, et le texte d’explication n’est vraiment pas clair

Oui, je me suis d’ailleurs inspir de GraphTest.

J’ai aussi regard les exemples dans Printing and Reporting, mais je n’ai rien trouv de vraiment inspirant

En rsum :

  • ce que je fais : dessiner dans un canvas - crer une picture - transfert du contenu du canvas vers la picture (drawinto) - impression
  • ce que tu proposes : crer une picture - dessiner dans la picture - transfert du contenu de la picture dans canvas (pour affichage l’cran ?) impression

J’avoue ne pas savoir choisir entre les deux solutions en terme de simplicit, robustesse, maintenance

Informations sommaires (rapides); demande si pas assez clair)

Pour DrawInto:

Installe un Listbox, fixe deux couleurs de fond, mets plusieurs colonnes et remplis les (dans Window1.Open).

Ensuite, dans un bouton, mets le code de DrawInto et place l’image dans le Clipboard (Presse-papiers).

Dans le Finder, Afficher le presse-papiers (Menu Edition): tu vois enfin ce à quoi peut servir DrawInto.

Pour l’offscreen Picture (écriture dans un Picture, affichage dans un Canvas):

Crée un objet Picture (tu l’as déjà) du nom de OSB_Pict
Utilises la référence à cet objet pour dessiner tes courbes (ou autres)
Lorsque tu as fini: Canvas1.Backdrop = OSB_Pict

Pour l’impression, utilise (code pris dans PrinterSetup):

Dim g As Graphics Dim p As PrinterSetup p = New PrinterSetup If p.PageSetupDialog Then g = OpenPrinterDialog(p) If g <> Nil Then g.DrawPicture OSB_Pict,10,10 // 10,10 est à ajuster à la demande… End If End If

Vérifie le code ci-dessus (il provient du guide du langage, mais j’ai pu me tromper sur g.DrawPicture).

Le choix entre plusieurs solutions ? Le bon sens, le bon fonctionnement du code, la différence de taille, etc.

Ne pas se braquer sur le manque de tests (f <> Nil .Exists, etc.) dans les exemples donnés ici; dans mon cas, je me concentre sur ce qui permet la compréhension / la résolution du problème, je laisse les détails au lecteur qui peut toujours demander après coup.

Enfin, je consulte les “manuels de références” (documentation.xojo.com, developer.xojo.com et en ligne) en permanence, surtout lorsque je ne me souviens pas si le contenu de l’objet est 0-based ou 1-based (commun en informatique). Le plus important est dans la logique du code, on s’aide des manuels pour son écriture et les détails :wink:

Bonne soirée.

Merci pour ton retour,

je testerai tes suggestions quand j’aurai un peu plus de temps.

Pour ce qui est de la recherche de solutions, je ne regarde que le “language reference” de la version actuelle , ce qui est visiblement insuffisant, ainsi qu’une version papier du language reference de la Version4 de RealBasic. Cette dernire m’est bien utile, car il me semble que les exemples sont plus nombreux et les explications sont plus accessibles.
Aujourd’hui, XOJOest compatible avec beaucoup plus de langages que RB. Cela entrane des explications et des exemples qui s’adressent au plus petit dnominateur commun entre un affichage sous OSX, Windows10, iOS, Raspberry PI, bref, compltement hors du contexte prcis d’utilisation du programmeur plant.

Pour prendre un exemple, si je me rfre au Language reference pour ListBox.drawInto, j’obtiens ceci

[quote]RectControl.DrawInto
Method

RectControl.DrawInto(g as Graphics,x as Integer, y as Integer)

Draws the contents of the RectControl into the specified Graphics context. The parameters x and y are the coordinates of the top, left corner.

Notes

This method does not work with HTMLViewer and OpenGLSurface.

Example

This example draws the current control into the Graphics of a Picture and then displays it as the Backdrop of a Canvas:

Dim p As New Picture(Me.Width, Me.Height, 32)
Me.DrawInto(p.Graphics, 0, 0)
Canvas1.Backdrop = p[/quote]

Ceci ne m’apprends pas grand chose ( part la signification de X et Y). Quant au rsultat concret Rien voir par exemple avec l’illustration de Hierarchical ListBoxes, qui soit dit en passant existait dj dans la RB4.

Le niveau d’aide en ligne des nouvelles versions correspond celui d’un initi de la fonction, qui, par essence n’en a pas besoin, sauf comme tu le dis toi-mme, comme aide mmoire.

Bon, ces rflexions devraient tre adresses plus aux dveloppeurs de XOJO qu’ toi, excuse-moi

Bonne journe

Pas de soucis.

DrawInto existe pour plusieurs Controls,c’est pourquoi ils on mis qu’une seule page "générique"…

J’avais imprimé celui de la version 1, puis j’y avais apporté les modifications (un coupde crayon) apparues pendant quelques temps, puis elle est devenue obsolète, puis tellement de pages, j’ai arrêté ;).

Je ne suis pas d’acccord à 100 %. Pour DrawInto, j’ai essayé la fonction car je voulais voir ce que ça faisait: j’ai passé un peu de temps, mais le résultat est splendide (et pas besoin de gérer les largeurs de colonnes) pour un test, voir à quoi ça ressemble ! J’étais bluffé.