Rasterizing with Alpha Channel in DynaPDFmbs Pro

Has anyone been successful rasterizing into a Xojo picture with alpha channel from a code-created PDF in the DynaPDFmbs Pro plugin? The following code gets me a (very nicely centered) raster image with a white background. Deleting the InitWhite line gets the same image, but with a black background. I want a transparent background or, at a minimum, one with my choice of color.

Call AlgoPDF.MyPDF.EndPage

GISx.RasterizedPDFimage = New Picture( 2 * DeepWindow.DeepCanvas.Width , 2 * DeepWindow.DeepCanvas.Height )

Dim myRasterizer As New DynaPDFRasterizerMBS( AlgoPDF.MyPDF , GISx.RasterizedPDFimage.Width , GISx.RasterizedPDFimage.Height )
Dim myPDFpage As DynaPDFPageMBS = AlgoPDF.MyPDF.GetPage( 1 )
Dim myRasterizerOptions As New DynaPDFRasterImageMBS
myRasterizerOptions.DefScale = myRasterizerOptions.kpsFitBest
myRasterizerOptions.InitWhite = TRUE
LocalReturn = myRasterizer.RenderPage( myPDFpage , myRasterizerOptions )
GISx.RasterizedPDFimage = myRasterizer.Pic
DeepWindow.DeepCanvas.Invalidate

Have you tried the constructor that allows you to render with alpha?


DynaPDFRasterizerMBS
.Constructor(PDF as DynaPDFMBS, Pic as Picture, RenderWithAlpha as boolean = false)

Thank you Kevin. This looks right, but when I replace my Dim Statement with:

Dim myRasterizer As DynaPDFRasterizerMBS
myRasterizer = DynaPDFRasterizerMBS.Constructor( AlgoPDF.MyPDF , GISx.RasterizedPDFimage , TRUE )

I get compiler error (“there is more than one method…”). I must have the constructor syntax wrong, but have been unable to find an example that actually does this. Is there something obvious?

It certainly appears that this expensive plug-in can produce rasterizations with alpha channels, but it is not clear that anyone has written code to actually do it. Certainly, the intuitive approaches, like replacing “InitWhite” with “initAlpha” are not available.

Perhaps in the future Monkeybread will add to their current examples one that takes an internally-generated pdf and produces an alpha-channel png from it.

I thought I sent you a project a few days ago!?

// *2 for higher DPI
Dim Width  As UInt32 = Self.Width  * 2
Dim Height As UInt32 = Self.Height * 2
Dim ScanlineLen As Int32 = Width * 4
Dim PixelFormat As UInt32 = pdf.kpxfBGRA

// we render here to memoryblock in case you need pixels in a memoryblock...
Dim Buffer As New Memoryblock(height * ScanlineLen)

Dim Rasterizer As New DynaPDFRasterizerMBS(pdf, Nil, buffer, width, Height, ScanlineLen, PixelFormat)

Dim options As New DynaPDFRasterImageMBS

options.DefScale = options.kpsFitBest
options.Flags = 0 // options.krfCompositeWhite
options.InitWhite = False // true


Dim page As DynaPDFPageMBS = pdf.GetPage(PageNumber)

If Rasterizer.RenderPage(page, options) Then
  
  // we use PictureMBS to display it
  Dim PP As New PictureMBS(Buffer, Width, Height, PictureMBS.ImageFormatBGRA, ScanlineLen)
  
  pic = pp.CopyPictureWithAlpha
  
Else
  // Failed to render page?
  pic = Nil
End If

  Self.Invalidate

As you see pixel format is one with alpha (kpxfBGRA), InitWhite is false to avoid filling with white and we don’t set krfCompositeWhite to avoid compositing to white.

Okay. I can confirm that Christian’s code does produce an image with alpha channel, but I am reluctant to let it into my code base because it has stuff I don’t understand (memory blocks , scanlines , etc.) and don’t want to understand. (What does a memory block have to do with an alpha channel?)

There is a tension between those who are bilingual (typically Xojo and C++) and who write code with one-letter variable names and those of us who are focused on an end application, who struggle to maintain our code, and who are supportive of the new Xojo syntax because, while it is more verbose, it is also more indicative of what is going on in each line of code.

It actually isn’t hard to understand.

First you have to remember that DynaPDF is a c library that doesn’t know anything about Xojo Pictures.

The following defines the width & height of the output which will be twice the width & height of whatever Self is.

Dim Width As UInt32 = Self.Width * 2
Dim Height As UInt32 = Self.Height * 2

The following defines the width of one row / line. We are multiplying Width * 4 because the format is RGBA which means 4 bytes per pixel.

Dim ScanlineLen As Int32 = Width * 4

The following defines the pixel format for the DynaPDF Rasteriser.

Dim PixelFormat As UInt32 = pdf.kpxfBGRA

The following creates a new memory block to hold the pixels generated by the DynaPDF Rasteriser:

Dim Buffer As New Memoryblock(height * ScanlineLen)

The following creates the DynaPDF Rasteriser pointing to the pixel buffer memory block we have created. It also needs to know the dimensions of the output + format of the output:

Dim Rasterizer As New DynaPDFRasterizerMBS(pdf, Nil, buffer, width, Height, ScanlineLen, PixelFormat)

After rendering the page we need to convert the memory block into a Xojo Picture. To do this we first need to create a PictureMBS which also points to the pixel buffer memory block. Like the DynaPDF Rasteriser, we need to tell PictureMBS the dimensions of the output + the format of the output. Finally, we can create a Xojo Picture by copying the content of the PictureMBS / memory block.

Dim PP As New PictureMBS(Buffer, Width, Height, PictureMBS.ImageFormatBGRA, ScanlineLen)

pic = pp.CopyPictureWithAlpha

At this point you can safely dispose (Nil) of the other variables if you wish as they are no longer required (PP, Rasterizer, page, options, Buffer).

1 Like

I do not want my grousing about complexity to undercut my enormous appreciation for Keving’s and christian’s willingness to help me through this. Christian, in particular, has over the years been unfailing in his willingness to help me. I now, at least, have the option of code that does what I want. Again, my thanks.

2 Likes