question

ZhongKarl-4358 avatar image
0 Votes"
ZhongKarl-4358 asked Castorix31 answered

Graphics to xps or pdf

i have a graphics is there any way to convert this graphics to xps file or a pdf file in c#
i got graphics like this :
Bitmap bmp=new Bitmap(100,100);
Graphics g=Graphics.FromImage(bmp);
g.DrawingString("xxx");

windows-api
· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

As far as I know, there is no Windows API that can directly convert Graphics to xps or pdf. Maybe you need to use other third-party libraries.

0 Votes 0 ·
ZhongKarl-4358 avatar image
1 Vote"
ZhongKarl-4358 answered

i can do it via Microsoft XPS Document Writer the code like this

         System.Drawing.Printing.PrintDocument p = new System.Drawing.Printing.PrintDocument();
         p.PrintPage += delegate(object sender1, System.Drawing.Printing.PrintPageEventArgs e1)
         {
             Draw(e1.Graphics, 13);
         };

         // now try to print
         try
         {
             System.Drawing.Printing.PrintController printController = new System.Drawing.Printing.StandardPrintController();
             p.PrintController = printController;
             //p.PrinterSettings.PrinterName = "Microsoft XPS Document Writer";
             p.PrinterSettings.PrintFileName = @"d:\test\123.xps"; // the file name set earlier
             p.PrinterSettings.PrintToFile = true;    // print to a file (i thought this would ignore the default printer)            
             p.Print();

         }
         catch (Exception ex)
         {
             // for the Bug I have described, this Exception doesn't happen.
             // it creates an XPS file, but the file is invalid in the cases mentioned
             System.Windows.MessageBox.Show("Error", "Printing Error", System.Windows.MessageBoxButton.OK);
         }

but there is a question ,i mush install Microsoft XPS Document Writer ,is there any way to call Microsoft XPS Document Writer 's api to export xps file

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

cheong00 avatar image
0 Votes"
cheong00 answered ZhongKarl-4358 commented

You can create a blank XPS OM, then draw whatever you want on it, finally write the package (i.e.: xpsPackage in example) to file.

Use Activator.CreateInstance() to instantiate the relevant COM interface. Use dynamic type to work on returned COM objects if you don't want to go through the pain to create P/Invoke version of those interfaces. Just note that you will not get intellisense if you code this way (minor drawback). For any constants you need to use, lookup the actual value from xpsobjectmodel.h in the Windows SDK.


· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

thanks for your answer!! but the way you showed is c++ ,is there any way to use c#

0 Votes 0 ·
Castorix31 avatar image
0 Votes"
Castorix31 answered Castorix31 edited

I did a test in C# with XPS OM interfaces, by adding a gradient, a text and an image, like in MS MFCXPSSample
It seems to work fine, but it is complicated (and I reduced the interfaces declarations by replacing some by IntPtr)

118763-xps-test.jpg

 // References:
 // https://docs.microsoft.com/en-us/windows/win32/printdocs/create-a-blank-xps-om
 // VCSamples\VC2010Samples\MFC\XPS\MFCXPSSample
    
 Guid CLSID_XpsOMObjectFactory = new Guid("E974D26D-3D9B-4D47-88CC-3872F2DC3585");
 Type XpsOMObjectFactoryType = Type.GetTypeFromCLSID(CLSID_XpsOMObjectFactory, true);
 IXpsOMObjectFactory pXpsFactory = (IXpsOMObjectFactory)Activator.CreateInstance(XpsOMObjectFactoryType);
 if (pXpsFactory != null)
 {
     IXpsOMPackage pXpsPackage = null;
     HRESULT hr = pXpsFactory.CreatePackage(out pXpsPackage);
     if (hr == HRESULT.S_OK)
     {
         IXpsOMDocumentSequence pXpsFDS = null;
         IntPtr opcPartUri = IntPtr.Zero;
         // Create the URI for the fixed document sequence part and then create the fixed document sequence
         hr = pXpsFactory.CreatePartUri("/pfixedDocumentCollectionequence.fdseq", out opcPartUri);
         hr = pXpsFactory.CreateDocumentSequence(opcPartUri, out pXpsFDS);
         if (opcPartUri != IntPtr.Zero)
             Marshal.Release(opcPartUri);
    
         IXpsOMDocument pXpsFD = null;
         // Create the URI for the document part and then create the document.
         hr = pXpsFactory.CreatePartUri("/Documents/1/FixedDocument.fdoc", out opcPartUri);
         hr = pXpsFactory.CreateDocument(opcPartUri, out pXpsFD);
         if (opcPartUri != IntPtr.Zero)
             Marshal.Release(opcPartUri);
    
         // Create a blank page
         // Size of the screen for the test
         int nWidth = Screen.PrimaryScreen.Bounds.Width;
         int nHeight = Screen.PrimaryScreen.Bounds.Height;
         //XPS_SIZE pageSize = new XPS_SIZE { width = 800, height = 600 };
         XPS_SIZE pageSize = new XPS_SIZE { width = nWidth, height = nHeight };
         float nFactorWidth = 2;
         float nFactorHeight = 2;
    
         IXpsOMPage pXpsPage = null;
         hr = pXpsFactory.CreatePartUri("/Documents/1/Pages/1.fpage", out opcPartUri);
         hr = pXpsFactory.CreatePage(ref pageSize, "en-US", opcPartUri, out pXpsPage);
         if (opcPartUri != IntPtr.Zero)
             Marshal.Release(opcPartUri);
    
         // Create a page reference for the page.
         IXpsOMPageReference pXpsPageRef = null;
         hr = pXpsFactory.CreatePageReference(pageSize, out pXpsPageRef);
         // Add the fixed document sequence to the package.
         hr = pXpsPackage.SetDocumentSequence(pXpsFDS);
         // Get the document collection of the fixed document sequence and then add the document to the collection.
         IXpsOMDocumentCollection pFixedDocumentCollection = null;
         hr = pXpsFDS.GetDocuments(out pFixedDocumentCollection);
         hr = pFixedDocumentCollection.Append(pXpsFD);
    
         // Get the page reference collection from the document and add the page reference and blank page.
         IXpsOMPageReferenceCollection pXpsPageRefCollection = null;
         hr = pXpsFD.GetPageReferences(out pXpsPageRefCollection);
         hr = pXpsPageRefCollection.Append(pXpsPageRef);
         hr = pXpsPageRef.SetPage(pXpsPage);
    
         // Gradient
    
         {
             XPS_COLOR xpsColorTopbar = new XPS_COLOR();
             XPS_POINT startPoint = new XPS_POINT();
             XPS_POINT endPoint = new XPS_POINT();
             IXpsOMGradientStop pXpsGradientStop1;
             IXpsOMGradientStop pXpsGradientStop2;
    
             //SetXPSColorToARGB(ref xpsColorTopbar, ColorTranslator.ToWin32(System.Drawing.Color.FromArgb(255, 0xE4, 0x3B, 0x2F)), 255);
             SetXPSColorToARGB(ref xpsColorTopbar, ColorTranslator.ToWin32(System.Drawing.Color.Blue), 192);
             hr = pXpsFactory.CreateGradientStop(ref xpsColorTopbar, IntPtr.Zero, 0.0f, out pXpsGradientStop1);
    
             //SetXPSColorToARGB(ref xpsColorTopbar, ColorTranslator.ToWin32(System.Drawing.Color.FromArgb(255, 0xEF, 0x79, 0x2F)), 255);
             SetXPSColorToARGB(ref xpsColorTopbar, ColorTranslator.ToWin32(System.Drawing.Color.Red), 192);
             hr = pXpsFactory.CreateGradientStop(ref xpsColorTopbar, IntPtr.Zero, 1.0f, out pXpsGradientStop2);
    
             startPoint.x = 375.75f;
             startPoint.y = 18.0f;
             endPoint.x = 375.75f;
             endPoint.y = 134.6f;
    
             IXpsOMLinearGradientBrush pTopbarBrush;
             hr = pXpsFactory.CreateLinearGradientBrush(pXpsGradientStop1, pXpsGradientStop2, ref startPoint, ref endPoint, out pTopbarBrush);
    
             startPoint.x = 20.5f;
             startPoint.y = 18.0f;
    
             XPS_SEGMENT_TYPE[] topbarSegmentTypes = new XPS_SEGMENT_TYPE[3]
             {
                 XPS_SEGMENT_TYPE.XPS_SEGMENT_TYPE_LINE,
                 XPS_SEGMENT_TYPE.XPS_SEGMENT_TYPE_BEZIER,
                 XPS_SEGMENT_TYPE.XPS_SEGMENT_TYPE_LINE
             };
             float[] topbarSegmentData = new float[10]
             {
                 20.5f, 134.6f,
                 322.76f, 102.91f, 476.79f, 105.27f, 594.0f, 116.63f,
                 594.0f, 18.0f
             };
             bool[] topbarSegmentStrokes = new bool[3]
             {
                 false, false, false
             };
    
             IXpsOMGeometry pXpsGeometry = null;
             IXpsOMGeometryFigure pXpsFigure = null;
             IXpsOMGeometryFigureCollection pXpsFigureCollection = null;
    
             hr = pXpsFactory.CreateGeometryFigure(ref startPoint, out pXpsFigure);
             pXpsFigure.SetIsClosed(true);
             pXpsFigure.SetIsFilled(true);
             hr = pXpsFigure.SetSegments(3, 10, topbarSegmentTypes, topbarSegmentData, topbarSegmentStrokes);
             hr = pXpsFactory.CreateGeometry(out pXpsGeometry);
             hr = pXpsGeometry.GetFigures(out pXpsFigureCollection);
             hr = pXpsFigureCollection.Append(pXpsFigure);
    
             // Create the topbar
             IXpsOMPath pPathTopbar;
             hr = pXpsFactory.CreatePath(out pPathTopbar);
             hr = pPathTopbar.SetFillBrushLocal(pTopbarBrush);
             hr = pPathTopbar.SetGeometryLocal(pXpsGeometry);
    
             IXpsOMVisualCollection pPageVisuals;
             hr = pXpsPage.GetVisuals(out pPageVisuals);
             hr = pPageVisuals.Append(pPathTopbar);
    
             if (pXpsGeometry != null)
                 Marshal.ReleaseComObject(pXpsGeometry);
             if (pXpsFigure != null)
                 Marshal.ReleaseComObject(pXpsFigure);
             if (pXpsFigureCollection != null)
                 Marshal.ReleaseComObject(pXpsFigureCollection);
             if (pPathTopbar != null)
                 Marshal.ReleaseComObject(pPathTopbar);
             if (pPageVisuals != null)
                 Marshal.ReleaseComObject(pPageVisuals);
         }
    
         // Image
    
         {
             string sTempPath = System.IO.Path.GetTempPath();
             sTempPath = String.Concat(sTempPath, "Little_Girl.jpg");
             using (var wc = new System.Net.WebClient())
             {
                 //wc.Headers.Add("user-agent", "Mozilla/5.0 (Windows NT 10.0; WOW64; rv: 52.0) Gecko/20100101 Firefox/52.0 SeaMonkey/2.49.4");
                 //wc.DownloadFileAsync(new Uri("https://image.ibb.co/buLv2e/Little_Girl3.jpg"), sTempPath);
                 wc.DownloadFile(new Uri("https://image.ibb.co/buLv2e/Little_Girl3.jpg"), sTempPath);
             }
             string sImageFileName = sTempPath;
             //string sImageFileName = "E:\\Flowers.jpg";
             //string sImageFileName = "E:\\Rose.jpg";
             //string sImageFileName = "E:\\Rose_small.png"; 
             //string sImageFileName = "E:\\Schtroumpfette.jpg";
             //string sImageFileName = "E:\\Little_Girl3.jpg";
             Bitmap bitmap = new Bitmap(sImageFileName);
    
             IStream imageStream = null;
             IntPtr imagePartUri = IntPtr.Zero;
             IntPtr pImageResource = IntPtr.Zero;
             hr = pXpsFactory.CreateReadOnlyStreamOnFile(sImageFileName, out imageStream);
    
             string sImagePartName = "/Resources/Images/1.jpg";
             hr = pXpsFactory.CreatePartUri(sImagePartName, out imagePartUri);
             hr = pXpsFactory.CreateImageResource(
                     imageStream,
                     XPS_IMAGE_TYPE.XPS_IMAGE_TYPE_JPEG,
                     // XPS_IMAGE_TYPE.XPS_IMAGE_TYPE_PNG,
                     imagePartUri,
                     out pImageResource);
    
             if (imagePartUri != IntPtr.Zero)
                 Marshal.Release(imagePartUri);
             if (imageStream != null)
                 Marshal.ReleaseComObject(imageStream);
    
             float nX = 100, nY = 150;
             IntPtr pImageBrushPtr = IntPtr.Zero;
             XPS_RECT xpsViewbox = new XPS_RECT { x = 0.0f, y = 0.0f, width = bitmap.Width * nFactorWidth, height = bitmap.Height * nFactorHeight };
             XPS_RECT xpsViewport = new XPS_RECT { x = nX, y = nY, width = bitmap.Width * nFactorWidth, height = bitmap.Height * nFactorHeight };
             XPS_POINT startPoint = new XPS_POINT { x = nX, y = nY };
    
             // Create the image brush
             hr = pXpsFactory.CreateImageBrush(pImageResource, ref xpsViewbox, ref xpsViewport, out pImageBrushPtr);
    
             XPS_SEGMENT_TYPE[] segmentTypes = new XPS_SEGMENT_TYPE[3]
             {
                 XPS_SEGMENT_TYPE.XPS_SEGMENT_TYPE_LINE,
                 XPS_SEGMENT_TYPE.XPS_SEGMENT_TYPE_LINE,
                 XPS_SEGMENT_TYPE. XPS_SEGMENT_TYPE_LINE
             };
             float[] segmentData = new float[6]
             {
                 nX + bitmap.Width * nFactorWidth, nY,
                 nX + bitmap.Width * nFactorWidth, nY + bitmap.Height * nFactorHeight,
                 nX, nY + bitmap.Height * nFactorHeight
             };
             bool[] segmentStrokes = new bool[3]
             {
                 false, false, false
             };
    
             IXpsOMGeometry pXpsGeometry = null;
             IXpsOMGeometryFigure pXpsFigure = null;
             IXpsOMGeometryFigureCollection pXpsFigureCollection = null;
             hr = pXpsFactory.CreateGeometryFigure(startPoint, out pXpsFigure);
             pXpsFigure.SetIsClosed(true);
             pXpsFigure.SetIsFilled(true);
             pXpsFigure.SetSegments(3, 6, segmentTypes, segmentData, segmentStrokes);
             hr = pXpsFactory.CreateGeometry(out pXpsGeometry);
             hr = pXpsGeometry.GetFigures(out pXpsFigureCollection);
             hr = pXpsFigureCollection.Append(pXpsFigure);
    
             // Create and add the image
             IXpsOMPath pImagePath;
             hr = pXpsFactory.CreatePath(out pImagePath);
             IXpsOMBrush pImageBrush = Marshal.GetObjectForIUnknown(pImageBrushPtr) as IXpsOMBrush;
             hr = pImagePath.SetFillBrushLocal(pImageBrush);
             hr = pImagePath.SetGeometryLocal(pXpsGeometry);
    
             IXpsOMVisualCollection pPageVisuals;
             hr = pXpsPage.GetVisuals(out pPageVisuals);
             hr = pPageVisuals.Append(pImagePath);
    
             if (pXpsGeometry != null)
                 Marshal.ReleaseComObject(pXpsGeometry);
             if (pXpsFigure != null)
                 Marshal.ReleaseComObject(pXpsFigure);
             if (pXpsFigureCollection != null)
                 Marshal.ReleaseComObject(pXpsFigureCollection);
    
             if (pImageResource != IntPtr.Zero)
                 Marshal.Release(pImageResource);
             if (pImageBrush != null)
                 Marshal.ReleaseComObject(pImageBrush);
             if (pPageVisuals != null)
                 Marshal.ReleaseComObject(pPageVisuals);
         } 
    
         // Text
    
         {
             string sText = "This is a XPS text";
             Guid FOLDERID_Fonts = new Guid("FD228CB7-AE11-4AE3-864C-16F3910AB8FE");
             IntPtr pString = IntPtr.Zero;
             hr = SHGetKnownFolderPath(FOLDERID_Fonts, 0, IntPtr.Zero, out pString);
             string sFontFileName = Marshal.PtrToStringUni(pString);
             //sFontFileName = String.Concat(sFontFileName, "\\Arial.ttf");
             sFontFileName = String.Concat(sFontFileName, "\\Times.ttf");
             // Create font stream.
             IStream fontStream = null;
             hr = pXpsFactory.CreateReadOnlyStreamOnFile(sFontFileName, out fontStream);
    
             // Create new obfuscated part name for this resource using a GUID.
             Guid fontNameGuid;
             hr = CoCreateGuid(out fontNameGuid);
             StringBuilder sbGuidString = new StringBuilder(50);
             StringFromGUID2(ref fontNameGuid, sbGuidString, sbGuidString.Capacity);
             // Create a URI string for this font resource that will place the font part in the /Resources/Fonts folder of the package.                  
             string sUriString = "/Resources/Fonts/";
             // Create the part name using the GUID string as the name and ".odttf" as the extension GUID string start and ends with 
             // curly braces so they are removed.
             // uriString = "/Resources/Fonts/676FC6CF-A245-4BCC-B2DA-0B75C5317651.odttf"
             sbGuidString.Remove(0, 1);
             sbGuidString.Remove(sbGuidString.Length - 1, 1);
             sUriString = String.Concat(sUriString, sbGuidString.ToString(), ".odttf");
    
             // Create the font URI interface.
             IntPtr fontUri = IntPtr.Zero;
             IntPtr fontResource = IntPtr.Zero;
             hr = pXpsFactory.CreatePartUri(sUriString, out fontUri);
             // Create the font resource.
             hr = pXpsFactory.CreateFontResource(fontStream, XPS_FONT_EMBEDDING.XPS_FONT_EMBEDDING_OBFUSCATED, fontUri, false, out fontResource);
             if (fontUri != IntPtr.Zero)
                 Marshal.Release(fontUri);
    
             if (fontStream != null)
                 Marshal.ReleaseComObject(fontStream);
    
             XPS_COLOR xpsColorText = new XPS_COLOR();
             SetXPSColorToARGB(ref xpsColorText, ColorTranslator.ToWin32(System.Drawing.Color.Yellow), 255);
             AppendSimpleText(pXpsFactory, fontResource, 35.00f, xpsColorText, 170.0f, 75.0f, sText, pXpsPage);
    
             if (fontResource != IntPtr.Zero)
                 Marshal.Release(fontResource);
         }
    
         // Create the XPS file
         string sFileName = "E:\\test_create_xps.xps";
         try
         {
             hr = pXpsPackage.WriteToFile(sFileName, IntPtr.Zero, FILE_ATTRIBUTE_NORMAL, false);
         }
         catch (Exception ex)
         {
             System.Windows.Forms.MessageBox.Show("Could not write file : " + sFileName + "\r\n" + ex.Message.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
         }
    
         if (pXpsFDS != null)
             Marshal.ReleaseComObject(pXpsFDS);
         if (pXpsFD != null)
             Marshal.ReleaseComObject(pXpsFD);
         if (pXpsPage != null)
             Marshal.ReleaseComObject(pXpsPage);
         if (pXpsPageRef != null)
             Marshal.ReleaseComObject(pXpsPageRef);
         if (pFixedDocumentCollection != null)
             Marshal.ReleaseComObject(pFixedDocumentCollection);
         if (pXpsPageRefCollection != null)
             Marshal.ReleaseComObject(pXpsPageRefCollection);                 
    
         Marshal.ReleaseComObject(pXpsPackage);
     }
     Marshal.ReleaseComObject(pXpsFactory);
 }   


Declarations : XPS OM



xps-test.jpg (46.9 KiB)
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.