Jump to content

Converting from PDN to JPG in code


Recommended Posts

In attempting to learn the PDN programming, I am writing a little utility that will convert my .pdn files to .jpg so that I can view them. I kind of followed the example in the PDNBench source. The code snippet below successfully reads in a two-layer .pdn file, but when I write out the file, I only see the second layer (text), not the two layers (photo + text) merged together as I expected. I assume that I am missing something with either document.flatten or the surface. Any suggestions would be helpful.

Thanks

Bill

           PdnFileType aPft = new PdnFileType();
           JpegFileType aJft = new JpegFileType();

           Document aDocument;

           Stream aInputStream = null;
           Stream aOutputStream = null;

           try
           {
               // Read pdn file from file system.  LayerTest.pdn is a pdn file with two layers.
               // The first layer is a photograph.  The second layer is just some random text.
               aInputStream = new FileStream(@"C:\TEMP\LayerTest.pdn", FileMode.Open);

               // Convert PFT stream ot a document.
               aDocument = aPft.Load(aInputStream);

               aInputStream.Close();

               // Flatten the document.
               aDocument.Flatten();

               // Set save parameters
               JpegSaveConfigToken aJpgToken = new JpegSaveConfigToken(100);
               ProgressEventHandler aHandler = null;
               Surface aSurface = ((BitmapLayer)aDocument.Layers[0]).Surface;

               // Create output streem.
               aOutputStream = new FileStream(@"C:\TEMP\LayerTest.jpg", FileMode.Create);

               // Save the document as a jpg file.
               aJft.Save(aDocument, aOutputStream, aJpgToken, aSurface, aHandler, false);

               aOutputStream.Close();
           }

           finally
           {
               if (aInputStream != null)
               {
                   aInputStream.Dispose();
               }

               if (aOutputStream != null)
               {
                   aOutputStream.Dispose();
               }
           }

Link to comment
Share on other sites

I seem to have gotten it to work with the following to changes:

 // Flatten the document.
Document aDocumentTemp = aDocument.Flatten();

and then

// Save the document as a jpg file.
aJft.Save(aDocumentTemp, aOutputStream, aJpgToken, aSurface, aHandler, false);

Doh!

Thanks

Bill

Link to comment
Share on other sites

You must not pass the Layer's Surface into the Save() function. You must allocate a new, blank Surface of the same size and pass that in. Otherwise everything will get messed up. That parameter is for a "scratch" surface for the function to do rendering, etc. on to. With your current code it is reading and writing in the same area of memory when it expects these two to not be aliased.

// bad bad bad bad bad bad bad bad
Surface aSurface = ((BitmapLayer)aDocument.Layers[0]).Surface;

// good
Surface aSurface = new Surface(aDocument.Size);

Also, you do not need to Flatten() before calling Save(). It already handles that.

The Paint.NET Blog: https://blog.getpaint.net/

Donations are always appreciated! https://www.getpaint.net/donate.html

forumSig_bmwE60.jpg

Link to comment
Share on other sites

Rick,

Thanks for the safety tips!

Bill

       private void btnConvert_Click(object sender, EventArgs e)
       {
           PdnFileType aPft = new PdnFileType();
           JpegFileType aJft = new JpegFileType();

           Document aDocument;

           Stream aInputStream = null;
           Stream aOutputStream = null;

           try
           {
               // Read pdn file from file system.
               aInputStream = new FileStream(@"C:\TEMP\LayerTest.pdn", FileMode.Open);

               // Convert PFT stream ot a document.
               aDocument = aPft.Load(aInputStream);

               aInputStream.Close();

               // Set save parameters.
               JpegSaveConfigToken aJpgToken = new JpegSaveConfigToken(100);
               ProgressEventHandler aHandler = null;
               Surface aSurface = new Surface(aDocument.Size);

               // Create output stream.
               aOutputStream = new FileStream(@"C:\TEMP\LayerTest.jpg", FileMode.Create);

               // Save the document as a jpg file.
               aJft.Save(aDocument, aOutputStream, aJpgToken, aSurface, aHandler, false);

               aOutputStream.Close();
           }

           finally
           {
               if (aInputStream != null)
               {
                   aInputStream.Dispose();
               }

               if (aOutputStream != null)
               {
                   aOutputStream.Dispose();
               }
           }

           MessageBox.Show("Done.");
       }

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...