Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Novacode Docx Create Image from Bitmap

Background

My project is urgent and requires that I iterate a large XML file and return Base64 encoded images.

Each image must be inserted into an MS Word doc, and I am using the DocX library for that.

I am converting the Base64 strings to bitmap with no problem.

Problem

For the life of me, I can't seem to get the bitmaps into a Novacode.Image object which can then be inserted to the document. NOTE: I already know how to convert to System.Drawing.Image format. It is Novacode.Image format (DocX) that is giving me grief.

If I try to convert a la (Novacode.Image)somebitmap; I get Can not cast expression of type Image to Bitmap. If I try to initialize a new Novacode.Image object I get Can not access internal constructor Image here.

Using C#, .NET 4, Forms App, lots of coffee.

Question

Only Novacode.Image objects can be inserted into the MS Word doc via the library, so how the heck do I get my bitmap in there??

I am bleary-eyed at this point so perhaps I am just missing something simple.

like image 811
Matt Cashatt Avatar asked Jan 10 '12 17:01

Matt Cashatt


2 Answers

You have to use the DocX.AddImage() method to create a Novacode.Image object.

Follow these 5 steps to add a image to a word document:

  1. Save your picture into a memory stream.
  2. Create the Novacode.Image object by calling AddImage() method.
  3. Create a picture by calling CreatePicture() on the Novacode.Image object created in step 2.
  4. Set the shape of the picture (if needed).
  5. Insert your picture into a pragraph.

The sample below shows how to insert a image into a word document:

using (DocX doc = DocX.Create(@"Example.docx"))
{
  using (MemoryStream ms = new MemoryStream())
  {
    System.Drawing.Image myImg = System.Drawing.Image.FromFile(@"test.jpg");

    myImg.Save(ms, myImg.RawFormat);  // Save your picture in a memory stream.
    ms.Seek(0, SeekOrigin.Begin);                    

    Novacode.Image img = doc.AddImage(ms); // Create image.

    Paragraph p = doc.InsertParagraph("Hello", false);

    Picture pic1 = img.CreatePicture();     // Create picture.
    pic1.SetPictureShape(BasicShapes.cube); // Set picture shape (if needed)

    p.InsertPicture(pic1, 0); // Insert picture into paragraph.

    doc.Save();
  }
}

Hope, this helps.

like image 112
Hans Avatar answered Oct 04 '22 18:10

Hans


Thanks Hans and Martin, I was able to use this as a basis for ensuring large image files (photos) are always sized to fit on the page. The max width and max height can be changed depending on your page size.

using (MemoryStream ms = new MemoryStream())
{
    System.Drawing.Image myImg = System.Drawing.Image.FromFile(imageDirectory + i.FileName);

    double xScale = 1;
    double yScale = 1;

    double maxWidthInches = 6.1; // Max width to fit on a page
    double maxHeightInches = 8.66; // Max height to fit on a page

    // Normalise the Horizontal and Vertical scale for different resolutions
    double hScale = ((double)96 / myImg.HorizontalResolution);
    double vScale = ((double)96 / myImg.VerticalResolution);

    // Scaling required to fit in x direction
    double imageWidthInches = myImg.Width / myImg.HorizontalResolution; // in inches using DPI
    if (imageWidthInches > maxWidthInches)
        xScale = maxWidthInches / imageWidthInches * hScale;

    // Scaling required to fit in y direction
    double imageHeightInches = myImg.Height / myImg.VerticalResolution;
    if (imageHeightInches > maxHeightInches)
        yScale = maxHeightInches / imageHeightInches * vScale;

    double finalScale = Math.Min(xScale, yScale); // Use the smallest of the two scales to ensure the picture will fit in both directions

    myImg.Save(ms, myImg.RawFormat); // Save your picture in a memory stream.
    ms.Seek(0, SeekOrigin.Begin);

    Novacode.Image img = document.AddImage(ms); // Create image.
    Paragraph p = document.InsertParagraph();
    Picture pic = img.CreatePicture(); // Create picture.

    //Apply final scale to height & width
    double width = Math.Round((double)myImg.Width * finalScale);
    double height = Math.Round((double)myImg.Height * finalScale);

    pic.Width = (int)(width);
    pic.Height = (int)(height);

    p.InsertPicture(pic); // Insert picture into paragraph.
}
like image 33
Josh Avatar answered Oct 04 '22 17:10

Josh