Renderowanie kształtów oddzielnie od dokumentu

Podczas przetwarzania dokumentów częstym zadaniem jest wyodrębnienie wszystkich obrazów znajdujących się w dokumencie i wyeksportowanie ich do lokalizacji zewnętrznej. To zadanie staje się proste dzięki Aspose.Words API, który już zapewnia funkcjonalność wyodrębniania i zapisywania danych obrazu. Czasami jednak może zaistnieć potrzeba wyodrębnienia w podobny sposób innych typów treści graficznych reprezentowanych przez inny typ obiektu rysunkowego, na przykład pole tekstowe zawierające akapity, kształty strzałek i mały obraz. Nie ma prostego sposobu renderowania tego obiektu, ponieważ jest to kombinacja poszczególnych elementów treści. Możesz także spotkać się z przypadkiem, gdy zawartość została zgrupowana w obiekt, który wygląda jak pojedynczy obraz.

Aspose.Words zapewnia funkcjonalność wyodrębniania tego typu treści w taki sam sposób, w jaki można wyodrębnić prosty obraz z kształtu jako renderowaną treść. W tym artykule opisano, jak wykorzystać tę funkcję do renderowania kształtów niezależnie od dokumentu.

Typy kształtów w Aspose.Words

Cała zawartość warstwy rysunku dokumentu jest reprezentowana przez węzeł Shape lub GroupShape w module obiektu dokumentu Aspose.Words (DOM). Taka zawartość może obejmować pola tekstowe, obrazy, autokształty, obiekty OLE itp. Niektóre pola są również importowane w postaci kształtów, np. pole INCLUDEPICTURE.

Prosty obraz jest reprezentowany przez węzeł Shape ShapeType.Image. Ten węzeł kształtu nie ma węzłów podrzędnych, ale dostęp do danych obrazu zawartych w tym węźle kształtu można uzyskać za pomocą właściwości Shape.ImageData. Z drugiej strony kształt może składać się z wielu węzłów podrzędnych. Na przykład kształt pola tekstowego reprezentowany przez właściwość ShapeType.TextBox może składać się z wielu węzłów, takich jak Paragraph i Table. Większość kształtów może zawierać węzły blokowe Paragraph i Table. Są to te same węzły, które pojawiają się w korpusie głównym. Kształty są zawsze częścią jakiegoś akapitu, albo umieszczane bezpośrednio w wierszu, albo zakotwiczone w Ustęp,, ale “pływające” w dowolnym miejscu strony dokumentu.

rendering-shapes-separately-from-a-document_1

Dokument może również zawierać zgrupowane kształty. Grouping można włączyć w Microsoft Word, zaznaczając wiele obiektów i klikając “Group” w menu wyświetlanym po kliknięciu prawym przyciskiem myszy.

rendering-shapes-separately-from-a-document_2

W Aspose.Words te grupy kształtów są reprezentowane przez węzeł GroupShape. Można je również wywołać w ten sam sposób, aby wyrenderować całą grupę na obraz.

rendering-shapes-separately-from-a-document_3

Format DOCX może zawierać specjalne typy obrazów, takie jak diagramy lub wykresy. Kształty te są również reprezentowane przez węzeł Shape w formacie Aspose.Words, który również zapewnia podobną metodę renderowania ich jako obrazów. Z założenia kształt nie może zawierać innego kształtu jako elementu podrzędnego, chyba że ten kształt jest obrazem (ShapeType.Image). Na przykład Microsoft Word nie pozwala na wstawienie pola tekstowego do innego pola tekstowego.

Opisane powyżej typy kształtów zapewniają specjalną metodę renderowania kształtów za pomocą klasy ShapeRenderer. Instancja klasy ShapeRenderer jest pobierana dla formatu Shape lub GroupShape za pomocą metody GetShapeRenderer lub poprzez przekazanie Shape do konstruktora klasy ShapeRenderer. Ta klasa zapewnia dostęp do elementów, które umożliwiają renderowanie kształtu do następujących elementów:

  • Plik na dysku przy użyciu metody przeciążenia Save
  • Przesyłanie strumieniowe przy użyciu przeciążenia metody Save
  • Obiekt graficzny .NET przy użyciu metod RenderToSize i RenderToScale

Renderowanie do pliku lub strumienia

Metoda Save zapewnia przeciążenia, które renderują kształt bezpośrednio do pliku lub strumienia. Obydwa przeciążenia akceptują instancję klasy ImageSaveOptions, która pozwala zdefiniować opcje renderowania kształtu. Działa to w taki sam sposób, jak metoda Document.Save. Mimo że ten parametr jest wymagany, można przekazać wartość null, określając, że nie ma żadnych opcji niestandardowych.

Kształt można wyeksportować w dowolnym formacie obrazu określonym w wyliczeniu SaveFormat. Na przykład obraz może być renderowany jako obraz rastrowy, taki jak JPEG, określając wyliczenie SaveFormat.Jpeg, lub jako obraz wektorowy, taki jak EMF, określając SaveFormat.Emf.

Poniższy przykład kodu ilustruje renderowanie kształtu do obrazu EMF niezależnie od dokumentu i zapisywanie na dysku:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET
ShapeRenderer r = shape.GetShapeRenderer();
// Define custom options which control how the image is rendered. Render the shape to the JPEG raster format.
ImageSaveOptions imageOptions = new ImageSaveOptions(SaveFormat.Emf)
{
Scale = 1.5f
};
dataDir = dataDir + "TestFile.RenderToDisk_out.emf";
// Save the rendered image to disk.
r.Save(dataDir, imageOptions);

Poniższy przykład kodu ilustruje renderowanie kształtu do obrazu JPEG niezależnie od dokumentu i zapisywanie do strumienia:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET
ShapeRenderer r = new ShapeRenderer(shape);
// Define custom options which control how the image is rendered. Render the shape to the vector format EMF.
ImageSaveOptions imageOptions = new ImageSaveOptions(SaveFormat.Jpeg)
{
// Output the image in gray scale
ImageColorMode = ImageColorMode.Grayscale,
// Reduce the brightness a bit (default is 0.5f).
ImageBrightness = 0.45f
};
dataDir = dataDir + "TestFile.RenderToStream_out.jpg";
FileStream stream = new FileStream(dataDir, FileMode.Create);
// Save the rendered image to the stream using different options.
r.Save(stream, imageOptions);

Klasa ImageSaveOptions umożliwia określenie różnych opcji kontrolujących sposób renderowania obrazu. Opisaną powyżej funkcjonalność można zastosować w ten sam sposób do węzłów GroupShape i Shape.

Renderowanie do obiektu graficznego .NET

Renderowanie bezpośrednio do obiektu Graphics umożliwia zdefiniowanie własnych ustawień i stanu obiektu Graphics. Typowy scenariusz obejmuje renderowanie kształtu bezpośrednio do obiektu Graphics pobranego z formularza Windows lub mapy bitowej. Podczas renderowania węzła Shape ustawienia wpłyną na wygląd kształtu. Można na przykład obrócić lub skalować kształt, używając metod RotateTransform lub ScaleTransform dla obiektu Graphics.

Poniższy przykład pokazuje, jak wyrenderować kształt do obiektu .NET Graphics niezależnie od dokumentu i zastosować obrót do renderowanego obrazu:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET
public static void RenderShapeToGraphics(string dataDir, Shape shape)
{
ShapeRenderer r = shape.GetShapeRenderer();
// Find the size that the shape will be rendered to at the specified scale and resolution.
Size shapeSizeInPixels = r.GetSizeInPixels(1.0f, 96.0f);
// Rotating the shape may result in clipping as the image canvas is too small. Find the longest side
// And make sure that the graphics canvas is large enough to compensate for this.
int maxSide = System.Math.Max(shapeSizeInPixels.Width, shapeSizeInPixels.Height);
using (Bitmap image = new Bitmap((int)(maxSide * 1.25), (int)(maxSide * 1.25)))
{
// Rendering to a graphics object means we can specify settings and transformations to be applied to
// The shape that is rendered. In our case we will rotate the rendered shape.
using (Graphics gr = Graphics.FromImage(image))
{
// Clear the shape with the background color of the document.
gr.Clear(shape.Document.PageColor);
// Center the rotation using translation method below
gr.TranslateTransform((float)image.Width / 8, (float)image.Height / 2);
// Rotate the image by 45 degrees.
gr.RotateTransform(45);
// Undo the translation.
gr.TranslateTransform(-(float)image.Width / 8, -(float)image.Height / 2);
// Render the shape onto the graphics object.
r.RenderToSize(gr, 0, 0, shapeSizeInPixels.Width, shapeSizeInPixels.Height);
}
dataDir = dataDir + "TestFile.RenderToGraphics_out.png";
image.Save(dataDir, ImageFormat.Png);
Console.WriteLine("\nShape rendered to graphics successfully.\nFile saved at " + dataDir);
}
}

Podobnie jak metoda RenderToSize, metoda Renderuj na rozmiar odziedziczona z NodeRendererBase jest przydatna do tworzenia miniatur treści dokumentu. Rozmiar kształtu jest określany przez konstruktora. Metoda RenderToSize akceptuje obiekt Graphics, współrzędne X i Y położenia obrazu oraz rozmiar obrazu (szerokość i wysokość), który zostanie narysowany na obiekcie Graphics.

Dokument Shape można renderować do określonej skali przy użyciu metody ShapeRenderer.RenderToScale odziedziczonej z klasy NodeRendererBase. Jest to podobne do metody Document.RenderToScale, która akceptuje te same główne parametry. Różnica między tymi dwiema metodami polega na tym, że w przypadku metody ShapeRenderer.RenderToScale zamiast rozmiaru dosłownego wybiera się wartość zmiennoprzecinkową, która skaluje kształt podczas jego renderowania. Jeśli wartość float wynosi 1,0, kształt będzie renderowany w 100% w stosunku do jego pierwotnego rozmiaru. Wartość zmiennoprzecinkowa wynosząca 0,5 zmniejszy rozmiar obrazu o połowę.

Renderowanie obrazu kształtu

Klasa Shape reprezentuje obiekty w warstwie rysunku, takie jak Autokształt, pole tekstowe, dowolny kształt, obiekt OLE, formant ActiveX lub obraz. Korzystając z klasy Shape, możesz tworzyć lub modyfikować kształty w dokumencie Microsoft Word. Ważną właściwością kształtu jest jego ShapeType. Kształty różnych typów mogą mieć różne możliwości w dokumencie programu Word. Na przykład tylko obrazy i kształty OLE mogą zawierać obrazy, podczas gdy większość kształtów może zawierać tylko tekst.

Poniższy przykład pokazuje, jak wyrenderować obraz Shape do obrazu JPEG niezależnie od dokumentu i zapisać go na dysku:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET
dataDir = dataDir + "TestFile.RenderShape_out.jpg";
// Save the Shape image to disk in JPEG format and using default options.
shape.GetShapeRenderer().Save(dataDir, null);

Pobieranie rozmiaru kształtu

Klasa ShapeRenderer zapewnia również funkcję pobierania rozmiaru kształtu w pikselach za pomocą metody GetSizeInPixels. Ta metoda akceptuje dwa parametry float (Single) – skalę i DPI, które są używane do obliczania rozmiaru kształtu podczas renderowania kształtu. Metoda zwraca obiekt Size, który zawiera szerokość i wysokość obliczonego rozmiaru. Jest to przydatne, gdy wymagana jest wcześniejsza znajomość rozmiaru renderowanego kształtu, na przykład podczas tworzenia nowej mapy bitowej z wyrenderowanego wyniku.

Poniższy przykład pokazuje, jak utworzyć nowy obiekt Bitmap i Graphics z szerokością i wysokością kształtu, który ma być renderowany:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET
Size shapeRenderedSize = shape.GetShapeRenderer().GetSizeInPixels(1.0f, 96.0f);
using (Bitmap image = new Bitmap(shapeRenderedSize.Width, shapeRenderedSize.Height))
{
using (Graphics g = Graphics.FromImage(image))
{
// Render shape onto the graphics object using the RenderToScale or RenderToSize methods of ShapeRenderer class.
}
}

W przypadku korzystania z metod RenderToSize lub RenderToScale rozmiar renderowanego obrazu jest również zwracany w obiekcie SizeF. Można to przypisać do zmiennej i użyć w razie potrzeby.

Właściwość SizeInPoints zwraca rozmiar kształtu mierzony w punktach (zobacz ShapeRenderer. Wynikiem jest obiekt SizeF zawierający szerokość i wysokość.