Convertire un file PNG in PDF con le funzioni del API di Cairo

Da Gambas-it.org - Wikipedia.

La libreria Cairo consente utilizzando alcune sue funzioni esterne, fra l'altro, di creare un file PDF (o anche SVG) partendo da un file immagine di tipo PNG.

Per fare ciò, si dovrà avere installata nel proprio sistema e si dovrà richiamare nel progetto Gambas la libreria condivisa: "libcairo.so.2.11600.0 "


Creare un file PDF da un solo file immagine PNG

Mostriamo un semplice esempio, nel quale verrà creato un file PDF partendo da un solo file immagine di tipo PNG:

Library "libcairo:2.11600.0"

' cairo_surface_t * cairo_image_surface_create_from_png (const char *filename)
' Creates a new image surface and initializes the contents to the given PNG file.
Private Extern cairo_image_surface_create_from_png(filename As String) As Pointer

' int cairo_image_surface_get_width (cairo_surface_t *surface)
' Get the width of the image surface in pixels.
Private Extern cairo_image_surface_get_width(Csurface As Pointer) As Integer

' int cairo_image_surface_get_height (cairo_surface_t *surface)
' Get the height of the image surface in pixels.
Private Extern cairo_image_surface_get_height(Csurface As Pointer) As Integer

' cairo_surface_t * cairo_pdf_surface_create(const char *filename, double width_in_points, double height_in_points)
' Creates a PDF surface of the specified size in points to be written to filename.
Private Extern cairo_pdf_surface_create(filename As String, width_in_points As Float, height_in_points As Float) As Pointer

' cairo_t* cairo_create(cairo_surface_t *target)
' Creates a new cairo_t with all graphics state parameters set to default values and with target as a target surface.
Private Extern cairo_create(target As Pointer) As Pointer

' void cairo_scale (cairo_t *cr, double sx, double sy)
' Modifies the current transformation matrix (CTM) by scaling the X and Y user-space axes by sx and sy respectively.
Private Extern cairo_scale(Ccr As Pointer, xF As Float, yF As Float)

' void cairo_set_source_surface (cairo_t *cr, cairo_surface_t *surface, double x, double y)
' This is a convenience function for creating a pattern from surface and setting it as the source in cr with cairo_set_source().
Private Extern cairo_set_source_surface(Ccr As Pointer, Csurface As Pointer, xf As Float, yf As Float)

' void cairo_paint (cairo_t *cr)
' A drawing operator that paints the current source everywhere within the current clip region.
Private Extern cairo_paint(Ccr As Pointer)

' void cairo_destroy(cairo_t *cr)
' Decreases the reference count on cr by one.
Private Extern cairo_destroy(cr As Pointer)

' void cairo_surface_destroy(cairo_surface_t *surface)
' Decreases the reference count on surface by one.
Private Extern cairo_surface_destroy(cairo_surface As Pointer)


Public Sub Main()

 Dim imago, surface, cairo As Pointer
 Dim w, h As Integer
  
' Carica il file immagine PNG, dal quale generare il file PDF:
 imago = cairo_image_surface_create_from_png("/percorso/del/file.png")
 If imago == 0 Then Error.Raise("Errore !")
   
' Ottiene le dimensioni in pixel del file immagine PNG caricato:
 w = cairo_image_surface_get_width(imago)
 h = cairo_image_surface_get_height(imago)
   
' Inizio fase creazione del file PDF:
 surface = cairo_pdf_surface_create("/percorso/di/destinazione/del/file.pdf", w, h)
 If surface == 0 Then Error.Raise("Errore !")
  
' Crea il contesto grafico "cairo_t" dai dati della superficie grafica del futuro PDF:
 cairo = cairo_create(surface)
 If cairo == 0 Then Error.Raise("Errore !")
  
' Scala l'immagine:
 cairo_scale(cairo, 1.0, 1.0)
   
' Inserisce i dati della superficie del file PNG nel contesto grafico del futuro file PDF:
 cairo_set_source_surface(cairo, imago, 0, 0)
   
 cairo_paint(cairo)
   
' Per generare il file PDF, è necessario distruggere il contesto grafico "cairo_t" e la superficie dell'immagine:
 cairo_destroy(cairo)
 cairo_surface_destroy(surface)
  
End


Creare un file PDF da un due (o più) file immagine PNG

Mostriamo un semplice esempio, nel quale verrà creato un file PDF partendo da due (o più) file immagine di tipo PNG:

Library "libcairo:2.11600.0"

' cairo_surface_t * cairo_image_surface_create_from_png (const char *filename)
' Creates a new image surface and initializes the contents to the given PNG file.
Private Extern cairo_image_surface_create_from_png(filename As String) As Pointer

' int cairo_image_surface_get_width (cairo_surface_t *surface)
' Get the width of the image surface in pixels.
Private Extern cairo_image_surface_get_width(Csurface As Pointer) As Integer

' int cairo_image_surface_get_height (cairo_surface_t *surface)
' Get the height of the image surface in pixels.
Private Extern cairo_image_surface_get_height(Csurface As Pointer) As Integer

' cairo_surface_t * cairo_pdf_surface_create(const char *filename, double width_in_points, double height_in_points)
' Creates a PDF surface of the specified size in points to be written to filename.
Private Extern cairo_pdf_surface_create(filename As String, width_in_points As Float, height_in_points As Float) As Pointer

' cairo_t* cairo_create(cairo_surface_t *target)
' Creates a new cairo_t with all graphics state parameters set to default values and with target as a target surface.
Private Extern cairo_create(target As Pointer) As Pointer

' void cairo_scale (cairo_t *cr, double sx, double sy)
' Modifies the current transformation matrix (CTM) by scaling the X and Y user-space axes by sx and sy respectively.
Private Extern cairo_scale(Ccr As Pointer, xF As Float, yF As Float)

' void cairo_set_source_surface (cairo_t *cr, cairo_surface_t *surface, double x, double y)
' This is a convenience function for creating a pattern from surface and setting it as the source in cr with cairo_set_source().
Private Extern cairo_set_source_surface(Ccr As Pointer, Csurface As Pointer, xf As Float, yf As Float)

' void cairo_paint (cairo_t *cr)
' A drawing operator that paints the current source everywhere within the current clip region.
Private Extern cairo_paint(Ccr As Pointer)

' void cairo_destroy(cairo_t *cr)
' Decreases the reference count on cr by one.
Private Extern cairo_destroy(cr As Pointer)

' void cairo_surface_destroy(cairo_surface_t *surface)
' Decreases the reference count on surface by one.
Private Extern cairo_surface_destroy(cairo_surface As Pointer)


Public Sub Main()

 Dim imago1, imago2, surface, cairo As Pointer
 
' Carica il primo file immagine PNG, dal quale generare il file PDF:
 immago1 = cairo_image_surface_create_from_png("/percorso/del/file1.png")
 If imago1 == 0 Then Error.Raise("Errore !")

' Carica il secondo file immagine PNG, dal quale generare il file PDF:
 imago2 = cairo_image_surface_create_from_png("/percorso/del/file2.png")
 If imago2 == 0 Then Error.Raise("Errore !")
  
' Inizio fase creazione del file PDF. Imposta una superficie delle dimensioni di un foglio A4:
 surface = cairo_pdf_surface_create("/percorso/di/destinazione/del/file.pdf", 2480, 3508)
 If surface == 0 Then Error.Raise("Errore !")
  
' Crea il contesto grafico "cairo_t" dai dati della superficie grafica del futuro PDF:
 cairo = cairo_create(surface)
 If cairo == 0 Then Error.Raise("Errore !")

' Imposta l'immagine del primo file PNG

' Scala l'immagine:
 cairo_scale(cairo, 1.0, 1.0)
   
' Inserisce i dati della superficie del file PNG nel contesto grafico del futuro file PDF:
 cairo_set_source_surface(cairo, imago1, 0, 0)
   
 cairo_paint(cairo)


' Imposta l'immagine del secondo file PNG

' Scala l'immagine:
 cairo_scale(cairo, 1.0, 1.0)
   
' Inserisce i dati della superficie del file PNG nel contesto grafico del futuro file PDF:
 cairo_set_source_surface(cairo, imago2, 300, 0)
   
 cairo_paint(cairo)
  
 
' Per generare il file PDF, è necessario distruggere il contesto grafico "cairo_t" e la superficie dell'immagine:
 cairo_destroy(cairo)
 cairo_surface_destroy(surface)
  
End


Riferimenti