Currently working with replacing Foxit SDK (PDF) with Aspose.PDF .
We are using Aspose.PDF for .Net in our c++ application using C++/CLI support.
Now working on Render functionality
Code Snippet:
C++ code:
Load(FreeImageIO* ioAspose, fi_handle handleAspose, int page, int flags, void* data)
{
CDC memDC;
SASPOSEPDF* pASPOSEPDF = (SASPOSEPDF*)data;
if (NULL != pASPOSEPDF->hASPOSEDoc)
{
localPageID = AsposeCLIUM_LoadPage(pASPOSEPDF->hASPOSEDoc, 0);
double AsposeWidth = AsposeCLIUM_GetPageWidth(localPageID);
double AsposeHeight = AsposeCLIUM_GetPageHeight(localPageID);
double Aw = fPDFScale * AsposeWidth; // scale the pdf to our desired DPI
double Ah = fPDFScale * AsposeHeight; // scale the pdf to our desired DPI
// END LIMIT_BMP
CSize Asz((int)Aw, (int)Ah);
// Create device context compatible with screen
if (memDC.CreateCompatibleDC(NULL))
{
if ((hBitmap = CreateDIBSection(memDC.GetSafeHdc(), &bmInfo, DIB_RGB_COLORS, (void**)&ptPixels, 0, NULL)) != NULL)
{
hBitmapOld = (HBITMAP)SelectObject(memDC.GetSafeHdc(), (HGDIOBJ)hBitmap); // HPQC LiveNote defect 2795
if (NULL != hBitmapOld)
{
memDC.FillSolidRect(0, 0, Asz.cx, Asz.cy, RGB(255, 255, 255));
// Use SDK to render bitmap of PDF page to bitmap
//FPDF_RenderPage(memDC.m_hDC, pPage, 0, 0, sz.cx, sz.cy, 0, 0);
AsposeCLIUM_RenderPage(memDC.m_hDC, localPageID, 0, 0, Asz.cx, Asz.cy, 0, 0);
// and transfer to FreeImage bitmap that is always 24 bits to
// assure FreeImage Multi-bitmap function compatibility
pFIBITMAP = FreeImage_Allocate(Asz.cx, Asz.cy, 24);
RLASSERT_NOTNULL(pFIBITMAP);
if (NULL != pFIBITMAP)
{
RLLOG_DEBUG("PluginPDF: FreeImage_Allocate success");
int nColors = FreeImage_GetColorsUsed(pFIBITMAP);
int nSuccess = GetDIBits(
memDC.m_hDC, hBitmap, 0,
FreeImage_GetHeight(pFIBITMAP),
FreeImage_GetBits(pFIBITMAP),
FreeImage_GetInfo(pFIBITMAP),
DIB_RGB_COLORS);
As we can see in C++ code we declared an object of class CDC and the handle is send to RenderPage function which then feeds the bitmap of the PDF to FreeImage which displays the PDF on the display pane in our MFC code.
C++/CLI project
#pragma managed---------------> .Net code
void AsposeCLIM_RenderPage(HDC hdc, int pageID, int x, int y, int width, int height, int rotate, int flags)
{
try
{
IntPtr hdcPtr = (IntPtr)hdc;
AsposePDFCLIWrapper^ CLIWrapper = gcnew AsposePDFCLIWrapper();
CLIWrapper->AsposeCLI_RenderPage(hdcPtr, pageID, x, y, width, height, rotate, flags);
}
catch (System::Exception^ e)
{
System::Console::WriteLine(e->Message);
throw; // Re-throw the exception to be caught in the unmanaged context
}
}
Here we are sending the HDC handle as IntPtr to .Net code
#Pragma unmanged ----------------> C++ code
extern “C” __declspec(dllexport) void AsposeCLIUM_RenderPage(HDC hdc, int pageID, int x, int y, int width, int height, int rotate, int flags)
{
try
{
AsposeCLIM_RenderPage(hdc, pageID, x, y, width, height, rotate, flags);
}
catch (const std::exception& e) {
// Log or handle the exception
std::cerr << "Exception: " << e.what() << std::endl;
}
catch (…) {
// Catch any other exceptions
std::cerr << “Unknown exception occurred.” << std::endl;
}
}
This code is called from C++ code which inturn call the managed code .
.Net Code
public void Aspose_RenderPagetoHDC(int pageID, IntPtr hdc, int width, int height)
{
Page page = pageDictionary[pageID].Item2;
MessageBox.Show($“Page width: {page.Rect.Width}”);
// string filepath = “C:\PDF_Folder\PDF_SinglePage.pdf”;
//IntPtr pDoc = Aspose_LoadDocument(filepath, null);
//byte[] fileData = System.IO.File.ReadAllBytes(filepath);
Stream stream = pageDictionary[pageID].Item1;
Document pdfDocument = new Document(stream);
Page pdfPage;
try
{
pdfPage = pdfDocument.Pages[1]; // Aspose.PDF pages are 1-based
MessageBox.Show($"pdfPage: {pdfPage.Rect.Width}");
}
catch (Exception ex)
{
Console.WriteLine($"Error during loading the page: {ex.Message}");
return;
}
// Create a resolution object
Resolution resolution = new Resolution(300); // 300 DPI is a common resolution
// Create a MemoryStream to hold the rendered page
using (MemoryStream memStream = new MemoryStream())
{
// Create a PngDevice with the specified width, height, and resolution
PngDevice pngDevice = new PngDevice(width, height, resolution);
try
{
// Render the page to the MemoryStream
pngDevice.Process(pdfPage, memStream);
MessageBox.Show($"MemoryStream: {stream.Length}");
}
catch (Exception ex)
{
// Log any exceptions
Console.WriteLine($"Error during pngDevice.Process: {ex.Message}");
MessageBox.Show($"MemoryStream: {ex.Message}");
return;
}
MessageBox.Show($"pngDevice.Process success");
// Create a Bitmap from the MemoryStream
using (Bitmap gdiBitmap = new Bitmap(memStream))
{
Graphics graphics;
try
{
graphics = Graphics.FromHdc(hdc);
}
catch (Exception ex)
{
// Log any exceptions
Console.WriteLine($"Error during Graphics.FromHdc: {ex.Message}");
return;
}
// Create a Graphics object from the HDC handle
using (graphics)
{
// Draw the bitmap onto the HDC
graphics.DrawImage(gdiBitmap, 0, 0, width, height);
}
}
}
}
When call this function i am encountering a exception “the type initializer for Aspose.PDF.XmpField threw an exception” when the line “pngDevice.Process(pdfPage, memStream);” is executed.
image.png (5.6 KB)
Note : The .Net code is generated as dll for C++ project integrated. But when I run the same .Net code as console application then \I am not facing any issue.