Differenze tra le versioni di "Generare un file immagine da una DrawingArea"
Riga 6: | Riga 6: | ||
==Utilizzare le sole funzioni di Gambas== | ==Utilizzare le sole funzioni di Gambas== | ||
− | L'uso delle sole funzioni fornite dirattemente da Gambas consente di adottare | + | L'uso delle sole funzioni fornite dirattemente da Gambas consente di adottare almeno tre modalità. |
===1<SUP>a</sup> modalità=== | ===1<SUP>a</sup> modalità=== | ||
− | La prima modalità richiede un procedimento più complesso, che può essere così brevemente esplicitato: | + | La prima modalità è la più semplice fra quelle previste in questa pagina. Viene utilizzata la Classe ''DesktopWindow''; e pertanto sarà necessario attivare i Componenti ''gb.desktop'' e ''gb.desktop.x11'' . |
+ | |||
+ | Mostriamo un esempio pratico: | ||
+ | '''Public''' Sub Form_Open() | ||
+ | |||
+ | With DrawingArea1 | ||
+ | .Background = Color.White | ||
+ | .W = 300 | ||
+ | .H = 40 | ||
+ | End With | ||
+ | |||
+ | '''End''' | ||
+ | |||
+ | |||
+ | '''Public''' Sub DrawingArea1_Draw() | ||
+ | |||
+ | Dim c As Integer[] = [Color.Blue, Color.Green, Color.Yellow, Color.Red] | ||
+ | Dim p As Float[] = [0, 0.34, 0.67, 1] | ||
+ | |||
+ | <FONT Color=gray>' ''Disegnamo all'interno della "DrawingArea":''</font> | ||
+ | With Paint | ||
+ | .Brush = .LinearGradient(0, 0, DrawingArea1.W, DrawingArea1.H, c, p) | ||
+ | .Rectangle(0, 0, DrawingArea1.W, DrawingArea1.H) | ||
+ | .Fill | ||
+ | .End | ||
+ | End With | ||
+ | |||
+ | '''End''' | ||
+ | |||
+ | |||
+ | '''Public''' Sub Button1_Click() | ||
+ | |||
+ | Dim dw As DesktopWindow | ||
+ | Dim pc As Picture | ||
+ | |||
+ | With dw = New DesktopWindow(DrawingArea1.Handle) | ||
+ | pc = .GetScreenshot(True) | ||
+ | End With | ||
+ | |||
+ | pc.Save("/tmp/immagine.png", 100) | ||
+ | |||
+ | '''End''' | ||
+ | |||
+ | |||
+ | ===2<SUP>a</sup> modalità=== | ||
+ | La seconda modalità richiede un procedimento più complesso, che può essere così brevemente esplicitato: | ||
* disegno e/o scrivo nella DrawingArea; | * disegno e/o scrivo nella DrawingArea; | ||
* [[Printer#Stampare_in_un_file_.pdf_o_.ps|creo il file PDF]] mediante la proprietà .OutputFile della Classe Printer; | * [[Printer#Stampare_in_un_file_.pdf_o_.ps|creo il file PDF]] mediante la proprietà .OutputFile della Classe Printer; | ||
Riga 80: | Riga 125: | ||
− | === | + | ===3<SUP>a</sup> modalità=== |
− | La | + | La terza modalità ha una procedura più semplice, ma si basa sostanzialmente nel disegnare la medesima cosa sia nella ''DrawingArea'' che in un distinto oggetto ''Image'', che poi verrà salvato. Pertanto, tale modalità appare una soluzione poco ''raffinata''. |
Mostriamo un semplice esempio pratico: | Mostriamo un semplice esempio pratico: |
Versione delle 01:10, 8 apr 2016
Per generare un file immagine dal disegno di una DrawingArea, si possono adottare almeno due procedure:
- utilizzare le sole funzioni di Gambas;
- utilizzare le funzioni esterne delle librerie di X11;
- utilizzare le funzioni esterne delle librerie di X11 e di Imlib2.
Indice
Utilizzare le sole funzioni di Gambas
L'uso delle sole funzioni fornite dirattemente da Gambas consente di adottare almeno tre modalità.
1a modalità
La prima modalità è la più semplice fra quelle previste in questa pagina. Viene utilizzata la Classe DesktopWindow; e pertanto sarà necessario attivare i Componenti gb.desktop e gb.desktop.x11 .
Mostriamo un esempio pratico:
Public Sub Form_Open() With DrawingArea1 .Background = Color.White .W = 300 .H = 40 End With End Public Sub DrawingArea1_Draw() Dim c As Integer[] = [Color.Blue, Color.Green, Color.Yellow, Color.Red] Dim p As Float[] = [0, 0.34, 0.67, 1] ' Disegnamo all'interno della "DrawingArea": With Paint .Brush = .LinearGradient(0, 0, DrawingArea1.W, DrawingArea1.H, c, p) .Rectangle(0, 0, DrawingArea1.W, DrawingArea1.H) .Fill .End End With End Public Sub Button1_Click() Dim dw As DesktopWindow Dim pc As Picture With dw = New DesktopWindow(DrawingArea1.Handle) pc = .GetScreenshot(True) End With pc.Save("/tmp/immagine.png", 100) End
2a modalità
La seconda modalità richiede un procedimento più complesso, che può essere così brevemente esplicitato:
- disegno e/o scrivo nella DrawingArea;
- creo il file PDF mediante la proprietà .OutputFile della Classe Printer;
- utilizzando il file PDF, converto la pagina PDF in una Image (è necessario attivare il componente gb.pdf);
- quindi salvo detta Image con il suo metodo .Save in un file immagine.
Mostriamo di seguito un esempio:
Public Sub DrawingArea1_Draw() With Paint .Brush = Paint.Color(Color.Red) .MoveTo(200, 200) .RelLineTo(0, 100) .Stroke .DrawText("Testo con DrawText", 10, 10, 20, 20) .End End With End Public Sub Button1_Click() With Printer1 .Configure .Orientation = 0 .Paper = 2 .Resolution = Desktop.Resolution ' Stampa/crea un file .pdf: .OutputFile = "/tmp/mio_file.pdf" .Print End With End Public Sub Printer1_Draw() DrawingArea1_Draw() End Public Sub Button2_Click() Dim pdf As New PdfDocument Dim i As New Image With pdf .Open("/tmp/mio_file.pdf") ' Se il file pdf è stato caricato correttamente... If .Ready = True Then ' ...allora convertiamo la prima pagina ("indice" delle pagine = 1) in una "Image": i = pdf[1].Image ' Infine salviamo l'Image in un file immagine ' (è necessario scegliere il tipo di file immagine fra quelli supportati): i.Save("/tmp/mio_file_immagine.xxx") Else Message.Error("<FONT color=darkred>Errore nel caricamento del file PDF !") Endif End With End
3a modalità
La terza modalità ha una procedura più semplice, ma si basa sostanzialmente nel disegnare la medesima cosa sia nella DrawingArea che in un distinto oggetto Image, che poi verrà salvato. Pertanto, tale modalità appare una soluzione poco raffinata.
Mostriamo un semplice esempio pratico:
Public Sub DrawingArea1_Draw() Disegno() End Public Sub Button1_Click() Dim im As Image ' Crea un'immagine delle medesime dimensioni della "DrawingArea": im = New Image(DrawingArea1.Width, DrawingArea1.Height, Color.White) With Paint .Begin(im) Disegno() End With im.Save("/tmp/immagine.png", 100) End Private Sub Disegno() ' Imposta il medesimo disegno sia per la "DrawingArea" che per l'oggetto "Image" With Paint .Brush = Paint.Color(Color.Red) .Ellipse(100, 10, 100, 100) .Stroke .End End With End
Uso delle funzioni esterne del API di X11
L'uso delle risorse della libreria esterna X11, opportunamente combinate con quelle di Gambas, consente un procedimento molto più snello ripetto al precedente. Tale modalità richiede nel codice Gambas la dichiarazione della libreria dinamica condivisa: "libX11.so.6.3.0"
Mostriamo di seguito un semplice esempio, nel quale disegneremo all'interno di una DrawingArea una riga colorata con tutta la gamma dei colori dal blu al rosso. Al termine salveremo in un file immagine il disegno presente nella DrawingArea.
Funziona solo su sistemi a 64-bit.
Library "libX11:6.3.0" Private Enum XYBitmap = 0, XYPixmap, ZPixmap ' Display *XOpenDisplay(char *display_name) ' Opens a connection to the X server that controls a display. Private Extern XOpenDisplay(display$ As String) As Pointer ' unsigned long XAllPlanes() ' Returns a value with all bits set to 1 suitable for use in a plane argument to a procedure. Private Extern XAllPlanes() As Long ' XImage *XGetImage(Display *display, Drawable d, int x, int y, unsigned int width, unsigned int height, unsigned long plane_mask, int format) ' Returns a pointer to an XImage structure. Private Extern XGetImage(displayP As Pointer, d As Long, xI As Integer, yI As Integer, wid As Integer, hei As Integer, plane_mask As Long, formatI As Integer) As Pointer ' XCloseDisplay(Display *display) ' Closes the connection to the X server for the display specified in the Display structure and destroys all windows. Private Extern XCloseDisplay(displayP As Pointer) Public Sub Form_Open() DrawingArea1.Background = Color.White End Public Sub DrawingArea1_Draw() Dim c As Integer[] = [Color.Blue, Color.Green, Color.Yellow, Color.Red] Dim p As Float[] = [0, 0.34, 0.67, 1] ' Disegnamo all'interno della "DrawingArea": With Paint .Brush = .LinearGradient(10, 40, 300, 40, c, p) .Rectangle(10, 40, 300, 40) .Fill .End End With End Public Sub Button1_Click() Dim dsp, XImage, immago, p, p1 As Pointer Dim bb As Byte[] Dim i As Integer Dim st As Stream Dim im As Image dsp = XOpenDisplay(Null) If dsp = 0 Then Error.Raise("Impossibile aprire una connessione al server X !") ' Otteniamo un puntatore alla "Struttura" contenente i dati dell'immagine disegnata nella "DrawingArea": XImage = XGetImage(dsp, DrawingArea1.Handle, 0, 0, DrawingArea1.W, DrawingArea1.H, XAllPlanes(), ZPixmap) If XImage = 0 Then Error.Raise("Impossibile ottenere un 'Puntatore' ai dati dell'immagine della DrawingArea !") ' Otteniamo l'indirizzo di memoria dei dati grezzi dell'immagine puntati dalla Struttura "XImage": immago = Pointer@(XImage + 16) bb = New Byte[] For i = 0 To (DrawingArea1.W * DrawingArea1.H * 4) - 1 bb.Push(Byte@(immago + i)) Next im = New Image(DrawingArea1.W, DrawingArea1.H) p = Object.Address(im) p1 = Pointer@(p + 16) ' Scriviamo i dati immagine grezzi, ottenuti dalla funzione XGetImage(), nell'area di memoria ' puntata dal membro "*data" della Struttura "GB_IMG" contenuta nel file sorgente ".../main/lib/image/gb.image.h": st = Memory p1 For Write bb.Write(st, 0, bb.Count) st.Close ' Generiamo dunque il file immagine: im.Save("/tmp/immagine.png", 100) ' Va in chiusura: XCloseDisplay(dsp) End
Uso delle funzioni esterne del API di X11 e di ImLib2
L'uso delle risorse delle librerie esterne X11 e ImLib2 richiede nel codice Gambas la dichiarazione delle seguenti librerie dinamiche condivise:
- "libX11.so.6.3.0"
- "libImlib2.so.1.4.6"
Mostriamo di seguito un semplice esempio, nel quale disegneremo all'interno di una DrawingArea una riga colorata con tutta la gamma dei colori dal blu al rosso. Al termine salveremo in un file immagine il disegno presente nella DrawingArea.
Funziona solo su sistemi a 64-bit.
Library "libX11:6.3.0" Private Enum XYBitmap = 0, XYPixmap, ZPixmap ' Display *XOpenDisplay(char *display_name) ' Opens a connection to the X server that controls a display. Private Extern XOpenDisplay(display$ As String) As Pointer ' unsigned long XAllPlanes() ' Returns a value with all bits set to 1 suitable for use in a plane argument to a procedure. Private Extern XAllPlanes() As Long ' XImage *XGetImage(Display *display, Drawable d, int x, int y, unsigned int width, unsigned int height, unsigned long plane_mask, int format) ' Returns a pointer to an XImage structure. Private Extern XGetImage(displayP As Pointer, d As Long, xI As Integer, yI As Integer, wid As Integer, hei As Integer, plane_mask As Long, formatI As Integer) As Pointer ' XCloseDisplay(Display *display) ' Closes the connection to the X server for the display specified in the Display structure and destroys all windows. Private Extern XCloseDisplay(displayP As Pointer) Library "libImlib2:1.4.6" ' Imlib_Image imlib_create_image_using_data(int width, int height, DATA32 * data) ' Creates an image from the image data - in the format of a DATA32 (32 bits) per pixel in a linear array - specified with the width and the height specified. Private Extern imlib_create_image_using_data(width As Integer, height As Integer, data As Pointer) As Pointer ' void imlib_context_set_image(Imlib_Image image) ' Sets the current image Imlib2 will be using with its function calls. Private Extern imlib_context_set_image(Imlib_Image As Pointer) ' void imlib_image_set_has_alpha(char has_alpha) ' Sets the alpha flag for the current image. Private Extern imlib_image_set_has_alpha(has_alpha As Boolean) ' void imlib_save_image(const char *filename) ' Saves the current image in the format specified by the current image's format settings to the filename. Private Extern imlib_save_image(filename As String) Public Sub Form_Open() DrawingArea1.Background = Color.White End Public Sub DrawingArea1_Draw() Dim c As Integer[] = [Color.Blue, Color.Green, Color.Yellow, Color.Red] Dim p As Float[] = [0, 0.34, 0.67, 1] ' Disegnamo all'interno della "DrawingArea": With Paint .Brush = .LinearGradient(10, 40, 300, 40, c, p) .Rectangle(10, 40, 300, 40) .Fill .End End With End Public Sub Button1_Click() Dim dsp, XImage, immago As Pointer dsp = XOpenDisplay(Null) If IsNull(dsp) Then Error.Raise("Impossibile aprire una connessione al server X !") ' Otteniamo un puntatore alla "Struttura" contenente i dati dell'immagine disegnata nella "DrawingArea": XImage = XGetImage(dsp, DrawingArea1.Handle, 0, 0, DrawingArea1.W, DrawingArea1.H, XAllPlanes(), ZPixmap) If XImage = 0 Then Error.Raise("Impossibile ottenere un 'Puntatore' ai dati dell'immagine della DrawingArea !") ' Otteniamo l'indirizzo di memoria dei dati grezzi dell'immagine puntati dalla Struttura "XImage": immago = Pointer@(XImage + 16) ' Viene creata l'immagine dai dati grezzi passando il "Puntatore" ai dati grezzi dell'immagine: immago = imlib_create_image_using_data(DrawingArea1.W, DrawingArea1.H, immago) If immago = 0 Then Error.Raise("Impossibile creare l'immagine dai dati grezzi acquisiti !") imlib_context_set_image(immago) ' L'immagine creata viene salvata in un file immagine. Al nome del file immagine da creare va indicata l'estensione del formato immagine desiderato: imlib_save_image("/percorso/dove/salvare/il/file/immagine.xxx") ' Va in chiusura: XCloseDisplay(dsp) End