Spire.Doc is a professional Word .NET library specifically designed for developers to create, read, write, convert and print Word document files. Get free and professional technical support for Spire.Doc for .NET, Java, Android, C++, Python.

Wed Dec 08, 2021 6:35 am

Hi Team

My requirement is first I need to extract all shapes from table(table inserted in Microsoft word doc) and save each extracted shape in PNG format with original size in another table.

I have attached input file screenshot for your reference.

Please let me know is it possible to do this through Spire doc api.

Thanks in advance

pr20080798
 
Posts: 159
Joined: Wed Jan 20, 2021 1:15 pm

Wed Dec 08, 2021 7:58 am

Hello,

Thanks for your inquiry!

Please refer to the following code to achieve your needs, here I also attached my input file for your reference.

Code: Select all
            Document doc = new Document();
            doc.LoadFromFile("E:/testdoc/12shapes.docx");

            Table hasShapesTable = doc.Sections[0].Tables[0] as Table;
            Table anotherTable = doc.Sections[0].Tables[1] as Table;

            //extract all shapes from table
            List<ShapeObject> shapes = new List<ShapeObject>();
            foreach(TableRow row in hasShapesTable.Rows)
            {
                foreach(TableCell cell in row.Cells)
                {
                    foreach(DocumentObject obj1 in cell.ChildObjects)
                    {
                        if(obj1 is Paragraph)
                        {
                            foreach(DocumentObject obj2 in (obj1 as Paragraph).ChildObjects)
                            {
                                if(obj2 is ShapeObject)
                                {
                                    shapes.Add(obj2 as ShapeObject);
                                }
                            }
                        }
                    }
                }
            }

            //save each extracted shape in PNG
            List<string> savePaths = new List<string>();
            for(int i = 0; i < shapes.Count; i++)
            {
                ShapeObject shape = shapes[i];
                shape.VerticalOrigin = VerticalOrigin.Page;
                shape.VerticalPosition = (float)shape.StrokeWeight;
                shape.HorizontalOrigin = HorizontalOrigin.Page;
                shape.HorizontalPosition = (float)shape.StrokeWeight;
                Document temp = new Document();
                temp.AddSection().AddParagraph().ChildObjects.Add(shape.Clone());
                temp.Sections[0].PageSetup.PageSize = new SizeF((float)(shape.Width+5), (float)(shape.Height+5));
                temp.Sections[0].PageSetup.Margins = new MarginsF(0, 0, 0, 0);
                Bitmap image = temp.SaveToImages(0, ImageType.Bitmap) as Bitmap;
                image.MakeTransparent(Color.White);
                string path = i + ".png";
                image.Save(path);
                savePaths.Add(path);
            }

            //add the shapes to another table
            int imageIndex = 0;
            foreach (TableRow row in anotherTable.Rows)
            {
                foreach (TableCell cell in row.Cells)
                {
                    if(imageIndex >= savePaths.Count)
                    {
                        imageIndex = 0;
                    }
                    DocPicture picture = new DocPicture(doc);
                    picture.LoadImage(savePaths[imageIndex]);
                    cell.AddParagraph().ChildObjects.Add(picture);
                    imageIndex++;
                }
            }

            doc.SaveToFile("afterchange.docx");


Sincerely,
Marcia
E-iceblue support team
User avatar

Marcia.Zhou
 
Posts: 858
Joined: Wed Nov 04, 2020 2:29 am

Thu Dec 09, 2021 2:13 am

Hi Marcia

Thanks a lot

I have gone through your code.

Bitmap image = temp.SaveToImages(0, ImageType.Bitmap) as Bitmap;
I am getting error while coverting BuffereImage type into Bitmap


//Please go through my code


try {
ShapeObject shapeObj = (ShapeObject) object;
String imageName = "Image_" + imageIndex + "." + "png";
imageFile = new File(tempFilePath + "/" + attachId + imageName);
Image image = convertShapeToImage(shapeObj);
ImageIO.write(img, "png", imageFile);

}
catch(Exception e) {
LOGGER.error("Shape is not supported");
}

public static Image convertShapeToImage(ShapeObject shapeObj) {
Document document = new Document();
Section section = document.addSection();
section.addParagraph().getChildObjects().add(shapeObj.deepClone());
Image image = document.saveToImages(0, ImageType.Bitmap);
document.close();
return image;
}



It is my code to handle shape object after extracting shape from table. I will convert shape object into image object and save image object in PNG format but PNG format image size is bigger than original size(It comes in A4 size with white space).my requirement is I have to maintain original size of shape while saving image in PNG format.


Please let me how can modify my code to reach my requirement.

Thanks in advance

pr20080798
 
Posts: 159
Joined: Wed Jan 20, 2021 1:15 pm

Thu Dec 09, 2021 5:41 am

Hello,

Thanks for your feedback!

Sorry that I provide a C# code before, Here I also attached a same code in Java, please refer to this code.

For the issue of the large image size with your code, please refer to the following code to change the page size and shape format.
Code: Select all
   public static Image convertShapeToImage(ShapeObject shapeObj) {
      Document document = new Document();
      Section section = document.addSection();

      // here you need to change the page size of the section and the shape style
      float linewidth = (float) shapeObj.getStrokeWeight();
      shapeObj.setHorizontalOrigin(HorizontalOrigin.Page);
      shapeObj.setVerticalOrigin(VerticalOrigin.Page);

      Dimension dimension = new Dimension();
      dimension.setSize(shapeObj.getWidth() + 5, shapeObj.getHeight() + 5);
      section.getPageSetup().setPageSize(dimension);
      section.getPageSetup().setMargins(new MarginsF(linewidth, linewidth, linewidth, linewidth));

      section.addParagraph().getChildObjects().add(shapeObj.deepClone());
      Image image = document.saveToImages(0, ImageType.Bitmap);
      document.close();
      return image;
   }


Sincerely,
Marcia
E-iceblue support team
User avatar

Marcia.Zhou
 
Posts: 858
Joined: Wed Nov 04, 2020 2:29 am

Thu Dec 09, 2021 7:08 am

Hi Marcia

Thank you Marcia .

Now images are not coming in A4 size but images are cropped .I have attached output file.

Dimension dimension = new Dimension();
dimension.setSize(shapeObj.getWidth() + 5, shapeObj.getHeight() + 5);

you are modifying width and height of the image here.But my requirement is shape size and image size should be same.

Please provide solution for this.

Thank you
Last edited by pr20080798 on Thu Dec 09, 2021 7:29 am, edited 1 time in total.

pr20080798
 
Posts: 159
Joined: Wed Jan 20, 2021 1:15 pm

Thu Dec 09, 2021 7:22 am

Hello,

Thanks for your reply!

To help us better investigate your issue, please provide us with the following information, thanks in advance.

1. your input files.
2. your system information (E.g. Win7, 64 bit).
3. the dpi of your computer.

Sincerely,
Marcia
E-iceblue support team
User avatar

Marcia.Zhou
 
Posts: 858
Joined: Wed Nov 04, 2020 2:29 am

Thu Dec 09, 2021 8:04 am

Thank you,

I have provided my system information below

-Win 10,64bit
- dpi - 1366 * 768

pr20080798
 
Posts: 159
Joined: Wed Jan 20, 2021 1:15 pm

Thu Dec 09, 2021 9:08 am

Hello,

Consider that the shape.getSize() did not include the line width of it, so it is necessary to add an extra length. If you do not want to set a fixed value, please refer to the following code to set this value according to the line width of the shape dynamically.
Code: Select all
   public static Image convertShapeToImage(ShapeObject shapeObj) {
      Document document = new Document();
      Section section = document.addSection();

      // here you need to change the page size of the section and the shape style
      float linewidth = (float) shapeObj.getStrokeWeight();
      shapeObj.setHorizontalOrigin(HorizontalOrigin.Page);
      shapeObj.setVerticalOrigin(VerticalOrigin.Page);

      // set the size based on the shape size and line width
      Dimension dimension = new Dimension();
      dimension.setSize(shapeObj.getWidth() + 2 * linewidth, shapeObj.getHeight() + 2 * linewidth);
      section.getPageSetup().setPageSize(dimension);
      section.getPageSetup().setMargins(new MarginsF(0, linewidth, linewidth, 0));

      section.addParagraph().getChildObjects().add(shapeObj.deepClone());
      Image image = document.saveToImages(0, ImageType.Bitmap);
      document.close();
      return image;
   }



Besides, the content of the file you provided is different with the screenshots you post before. I tested with this file and the shape did not be cropped. Here I also attached my result file. Please provide us with the file you were using as your screenshots shown. Thanks in advance.

Sincerely,
Marcia
E-iceblue support team
User avatar

Marcia.Zhou
 
Posts: 858
Joined: Wed Nov 04, 2020 2:29 am

Thu Dec 09, 2021 9:39 am

Thank you.

I have attached input file.


Thanks in advance

pr20080798
 
Posts: 159
Joined: Wed Jan 20, 2021 1:15 pm

Thu Dec 09, 2021 10:16 am

Hello,

Thanks for sharing more information!

Please refer to the following code to reset the text wrap style of the shape to avoid being cropped, just like shown in the screenshot.
Code: Select all
shapeObj.setTextWrappingStyle(TextWrappingStyle.Inline);


place.png


Sincerely,
Marcia
E-iceblue support team
User avatar

Marcia.Zhou
 
Posts: 858
Joined: Wed Nov 04, 2020 2:29 am

Thu Dec 09, 2021 11:04 am

Thank you so much Marcia for providing solution.

Now Image is not cropping. I checked shape size and image size, both are not same.

public static Image convertShapeToImage(ShapeObject shapeObj) {

System.out.println("shapes height "+shapeObj.getHeight());
System.out.println("shapes width "+shapeObj.getWidth());

Image image = document.saveToImages(0, ImageType.Bitmap);

System.out.println("images height "+image.getHeight(null));
System.out.println("images width "+image.getWidth(null));

}

output :
---- shape---5
shape height 110.25
shape width 70.5
image height 150
image width 97

---- shape---6
shape height 102.0
shape width 80.25
image height 138
image width 110


Please let me know why shape and images size are not same

pr20080798
 
Posts: 159
Joined: Wed Jan 20, 2021 1:15 pm

Fri Dec 10, 2021 1:32 am

Hello,

As I told in the last post, the shapeObj.getHeight() and shapeObj.getWidth() do not include the line width of the shape, in order to display the entire shape, the size of the final image will increase the length of the line width, so the final size will be inconsistent.

What's more, the DPI of your computer also influence the size of the final image. Please check your DPI of your computer like the screenshot shown.
DPI.png


In addition, in our product, the unit of length is pt, and the unit of Image class in Java is px. So you cannot directly compare the two values.

Sincerely,
Marcia
E-iceblue support team
User avatar

Marcia.Zhou
 
Posts: 858
Joined: Wed Nov 04, 2020 2:29 am

Return to Spire.Doc