- Add a link to PDF with an external destination
- Add a link with an internal destination to PDF
- Add a note to PDF
- Add barcodes to PDF
- Add bookmarks to PDF
- Add footer to PDF
- Add simple html text to PDF
- Add hyperlink to PDF
- Add Long Term Validation (LTV) data to an existing signature
- Add multiline text to a PDF document
- Add a rubber stamp annotation with a custom icon
- Add single-line text to PDF
- Add Stamp to PDF
- Add tags to existing PDF
- Add text field to PDF
- Add a Diagonal Watermark to PDF in C# - TallComponents - PDF Library
- pdfkit5 - detailed changes to the API - Tall Components
- Append two or more existing PDF files
- Change the color inside a PDF
- Change the formatting of a numeric field
- Change page orientation PDF
- Clip PDF page content in C#
- .NET Core console app on MacOS
- Convert PDF to plain text
- Convert SVG to PDF
- Create a text annotation in PDF with rich text
- Create formfields in PDF documents
- Create a new digitally signed PDF document
- Create rectangles with rounded corners
- Create tagged PDF
- Create text with decorations
- How to create a tiling for shapes in PDF
- Crop content on a PDF page
- Determine the content bounding box
- Determine if a PDF only contains images
- Digitally sign a PDF form in C# or VB.NET
- Disable submit button after submitting
- How to downscale all images in a PDF
- Download and convert image to PDF
- How to downscale all images in a PDF
- Vector graphics in PDF
- Fill XFA form and export XDP data
- Fill and save dynamic XFA form
- Merge XDP data with dynamic XFA form
- Dynamic XFA
- How to embed files in a PDF document
- Embed TrueType font in PDF
- EMF to PDF as vector image
- Export FDF from PDF form
- Extract embedded files from PDF
- Extract glyph boxes from PDF
- Extract glyphs and sort by reading order
- Extract graphics from PDF
- Extract images from PDF
- Fill in a template PDF document
- Fill PDF form
- Fit image to PDF page
- Flatten Markup Annotation
- Flatten PDF form
- How to generate and export certificates
- How do I extract page destinations from bookmarks?
- Highlight fields in PDF
- How to add autosized text to PDF
- How to sign and verify updates to a PDF document
- Import FDF into PDF
- Licensing and .NET Standard
- Merge PDF files in C# .NET
- How to mirror PDF pages and other shapes
- Layout text with MultilineTextShape
- pdfkit5 and .NET Core
- pdfkit5 .NET Standard API
- Read and write meta data from PDF
- Read PDF tags
- How to reduce PDF file size
- Reduce PDF size
- Remove graphics from PDF
- Remove PDF security settings
- Replace field with image
- Resize PDF pages
- Rotate a PDF page
- How to scale content of PDF
- Search text in PDF
- PDF Viewer Preferences
- Create a custom signature handler to sign and verify PDF documents
- Split PDF pages in C# and VB.NET
- Tagged PDF
- TIFF to PDF C#
- Translate PDF page content
- Use multiple licenses
- Use TrueType font collections
- Write Document to HttpResponse
- Use pdfkit5 with a Xamarin.Forms app
- pdfkit5 and Xamarin
Remove graphics from PDF
This code sample shows how to partly erase images from a PDF under an explicitly specified rectangle. For brushes and rectangles the namespace is mentioned explicitly to avoid confusion as both classes occur in the System.Drawing namespace as well as in the TallComponents.PDF namespace.
In the main method we replace an existing page with a newly created one. On the new page we add edited collection of shapes from the original page.
const string inputFileName = @"..\..\..\inputDocuments\redaction.pdf";
const string outputFileName = "out.pdf";
using (FileStream input = File.Open(inputFileName, FileMode.Open))
using (FileStream output = File.Create(outputFileName))
{
// open file for editing
Document doc = new Document(input);
// page to edit
Page page = doc.Pages[0];
ShapeCollection shapes = page.CreateShapes();
// create new page there modfied content will be stored
Page newPage = page.Clone(PageCloneSettings.NoOriginalGraphics);
// specify the area to clear and a brush to use
TallComponents.PDF.Rectangle clearRect = new TallComponents.PDF.Rectangle(250, 200, 200, 400);
System.Drawing.Brush clearBrush = Brushes.Red;
// run the clear routine
ClearArea(shapes, clearRect, clearBrush, new Matrix());
// copy the edited content
newPage.Overlay.Add(shapes);
// replace old page with new one
doc.Pages.RemoveAt(0);
doc.Pages.Insert(0, newPage);
doc.Write(output);
}
Process.Start(outputFileName);
Const inputFileName As String = "..\..\..\inputDocuments\redaction.pdf"
Const outputFileName As String = "out.pdf"
Using input As FileStream = File.Open(inputFileName, FileMode.Open)
Using output As FileStream = File.Create(outputFileName)
' open file for editing
Dim doc As New Document(input)
' page to edit
Dim page As Page = doc.Pages(0)
Dim shapes As ShapeCollection = page.CreateShapes()
' create new page there modfied content will be stored
Dim newPage As Page = page.Clone(PageCloneSettings.NoOriginalGraphics)
' specify the area to clear and a brush to use
Dim clearRect As New TallComponents.PDF.Rectangle(250, 200, 200, 400)
Dim clearBrush As System.Drawing.Brush = Brushes.Red
' run the clear routine
ClearArea(shapes, clearRect, clearBrush, New Matrix())
' copy the edited content
newPage.Overlay.Add(shapes)
' replace old page with new one
doc.Pages.RemoveAt(0)
doc.Pages.Insert(0, newPage)
doc.Write(output)
End Using
End Using
Process.Start(outputFileName)
The ClearArea method enumerates all the shapes inside the given shape collection. The method replaces all occurrences of the ImageShape(that are overlapped by the given rectangular area) with an edited ImageShape.
public static void ClearArea(ShapeCollection shapes, TallComponents.PDF.Rectangle area,
System.Drawing.Brush clearBrush, Matrix transform)
{
// set the current transform for the collection
Matrix currentTransform = GetShapeTransform(shapes, transform);
// examine shapes in order to find the image and edit it.
for (int i = 0; i < shapes.Count; i++)
{
Shape shape = shapes[i];
if (shape is ImageShape)
{
// process the image shape
ImageShape imageShape = shape as ImageShape;
// determine whether the imageShape is overlapped by
// the given rectangle
TallComponents.PDF.Rectangle imageShapeRect = GetImageShapeRectangle(imageShape, currentTransform);
RectangleF intersectionRect = IntersectRectangles(area, imageShapeRect);
if (!intersectionRect.IsEmpty)
{
// clear overlapped area of the image shape
ImageShape clearedImageShape = ClearImageArea(imageShape, intersectionRect,
clearBrush, currentTransform);
// replace the old image shape with new one
shapes.RemoveAt(i);
shapes.Insert(i, clearedImageShape);
}
}
else if (shape is ShapeCollection) //continue recursively
{
ClearArea(shape as ShapeCollection, area, clearBrush, currentTransform);
}
}
}
``` vb
Public Sub ClearArea(shapes As ShapeCollection, area As TallComponents.PDF.Rectangle, clearBrush As System.Drawing.Brush, transform As Matrix)
' set the current transform for the collection
Dim currentTransform As Matrix = GetShapeTransform(shapes, transform)
' examine shapes in order to find the image and edit it.
For i As Integer = 0 To shapes.Count - 1
Dim shape As Shape = shapes(i)
If TypeOf shape Is ImageShape Then
' process the image shape
Dim imageShape As ImageShape = TryCast(shape, ImageShape)
' determine whether the imageShape is overlapped by
' the given rectangle
Dim imageShapeRect As TallComponents.PDF.Rectangle = GetImageShapeRectangle(imageShape, currentTransform)
Dim intersectionRect As RectangleF = IntersectRectangles(area, imageShapeRect)
If Not intersectionRect.IsEmpty Then
' clear overlapped area of the image shape
Dim clearedImageShape As ImageShape = ClearImageArea(imageShape, intersectionRect, clearBrush, currentTransform)
' replace the old image shape with new one
shapes.RemoveAt(i)
shapes.Insert(i, clearedImageShape)
End If
ElseIf TypeOf shape Is ShapeCollection Then
'continue recursively
ClearArea(TryCast(shape, ShapeCollection), area, clearBrush, currentTransform)
End If
Next
End Sub
The ClearImageArea method clears parts of the image shapes that are underneath the given rectangular area using given brush.
private static ImageShape ClearImageArea(ImageShape imageShape, RectangleF area, System.Drawing.Brush clearBrush,
Matrix transform)
{
TallComponents.PDF.Rectangle shapeRect = GetImageShapeRectangle(imageShape, transform);
double scaleX = imageShape.Width / shapeRect.Width;
double scaleY = imageShape.Height / shapeRect.Height;
area = new RectangleF((float)(area.X * scaleX), (float)(area.Y * scaleY),
(float)(area.Width * scaleX), (float)(area.Height * scaleY));
// extract bitmap and prepare for editing
Bitmap bitmap = imageShape.CreateBitmap();
bitmap.SetResolution((float)imageShape.HorizontalResolution, (float)imageShape.VerticalResolution);
// clear a part of the bitmap
using (Graphics g = Graphics.FromImage(bitmap))
{
if (IsFlipped(imageShape, transform))
{
g.Transform = new Matrix(1, 0, 0, -1, 0, bitmap.Height);
}
g.FillRectangle(clearBrush, area);
}
// return a new image shape with the edited bitmap
return new ImageShape(bitmap) { Transform = imageShape.Transform };
}
``` vb
Private Function ClearImageArea(imageShape As ImageShape, area As RectangleF, clearBrush As System.Drawing.Brush, transform As Matrix) As ImageShape
Dim shapeRect As TallComponents.PDF.Rectangle = GetImageShapeRectangle(imageShape, transform)
Dim scaleX As Double = imageShape.Width / shapeRect.Width
Dim scaleY As Double = imageShape.Height / shapeRect.Height
area = New RectangleF(CSng(area.X * scaleX), CSng(area.Y * scaleY), CSng(area.Width * scaleX), CSng(area.Height * scaleY))
' extract bitmap and prepare for editing
Dim bitmap As Bitmap = imageShape.CreateBitmap()
bitmap.SetResolution(CSng(imageShape.HorizontalResolution), CSng(imageShape.VerticalResolution))
' clear a part of the bitmap
Using g As Graphics = Graphics.FromImage(bitmap)
If IsFlipped(imageShape, transform) Then
g.Transform = New Matrix(1, 0, 0, -1, 0, bitmap.Height)
End If
g.FillRectangle(clearBrush, area)
End Using
' return a new image shape with the edited bitmap
Dim shape = New ImageShape(bitmap)
shape.Transform = imageShape.Transform
Return shape
End Function
]]></code>
</codesnippet>
Few utility methods that are used in the code above.
``` csharp
private static TallComponents.PDF.Rectangle GetImageShapeRectangle(ImageShape imageShape, Matrix transform)
{
Matrix shapeTransform = GetShapeTransform(imageShape, transform);
// get the transformed shape rect
PointF[] points = new[] { new PointF(0, 0),
new PointF((float)(imageShape.Width), (float)(imageShape.Height)) };
shapeTransform.TransformPoints(points);
double width = points[1].X - points[0].X;
double height = points[1].Y - points[0].Y;
// flipped, so fix the rect
if (height < 0)
{
PointF tmpPoint = points[0];
points[0] = new PointF(points[0].X, points[1].Y);
points[1] = new PointF(points[1].X, tmpPoint.Y);
height = -height;
}
return new TallComponents.PDF.Rectangle(points[0].X, points[0].Y, width, height);
}
private static Matrix GetShapeTransform(ContentShape shape, Matrix transform)
{
Matrix shapeTransform = transform.Clone();
if (shape.Transform != null)
{
shapeTransform.Multiply(shape.Transform.CreateGdiMatrix());
}
return shapeTransform;
}
private static bool IsFlipped(ImageShape imageShape, Matrix transform)
{
Matrix shapeTransform = GetShapeTransform(imageShape, transform);
// get the transformed shape rect
PointF[] points = new[] { new PointF(0, 0),
new PointF((float)(imageShape.Width), (float)(imageShape.Height)) };
shapeTransform.TransformPoints(points);
return (points[1].Y - points[0].Y < 0);
}
static RectangleF IntersectRectangles(TallComponents.PDF.Rectangle rect1, TallComponents.PDF.Rectangle rect2)
{
double rect2Right = rect2.Left + rect2.Width;
double rect2Top = rect2.Bottom + rect2.Height;
double rect1Right = rect1.Left + rect1.Width;
double rect1Top = rect1.Bottom + rect1.Height;
if ((rect2Right < rect1.Left || rect2.Left > rect1Right) ||
(rect2.Bottom > rect1Top || rect2Top < rect1.Bottom))
{
return RectangleF.Empty;
}
double left = Math.Max(rect1.Left, rect2.Left);
double bottom = Math.Max(rect1.Bottom, rect2.Bottom);
double width = Math.Min(rect1Right, rect2Right) - left;
double height = Math.Min(rect1Top, rect2Top) - bottom;
float x = (float)((left - rect2.Left));
float y = (float)(rect2.Height - (bottom + height - rect2.Bottom));
RectangleF rect = new RectangleF(x, y, (float)width, (float)height);
return rect;
}
Private Function GetImageShapeRectangle(imageShape As ImageShape, transform As Matrix) As TallComponents.PDF.Rectangle
Dim shapeTransform As Matrix = GetShapeTransform(imageShape, transform)
' get the transformed shape rect
Dim points As PointF() = {New PointF(0, 0), New PointF(CSng(imageShape.Width), CSng(imageShape.Height))}
shapeTransform.TransformPoints(points)
Dim width As Double = points(1).X - points(0).X
Dim height As Double = points(1).Y - points(0).Y
' flipped, so fix the rect
If height < 0 Then
Dim tmpPoint As PointF = points(0)
points(0) = New PointF(points(0).X, points(1).Y)
points(1) = New PointF(points(1).X, tmpPoint.Y)
height = -height
End If
Return New TallComponents.PDF.Rectangle(points(0).X, points(0).Y, width, height)
End Function
Private Function GetShapeTransform(shape As ContentShape, transform As Matrix) As Matrix
Dim shapeTransform As Matrix = transform.Clone()
If shape.Transform IsNot Nothing Then
shapeTransform.Multiply(shape.Transform.CreateGdiMatrix())
End If
Return shapeTransform
End Function
Private Function IsFlipped(imageShape As ImageShape, transform As Matrix) As Boolean
Dim shapeTransform As Matrix = GetShapeTransform(imageShape, transform)
' get the transformed shape rect
Dim points As PointF() = {New PointF(0, 0), New PointF(CSng(imageShape.Width), CSng(imageShape.Height))}
shapeTransform.TransformPoints(points)
Return (points(1).Y - points(0).Y < 0)
End Function
Private Function IntersectRectangles(rect1 As TallComponents.PDF.Rectangle, rect2 As TallComponents.PDF.Rectangle) As RectangleF
Dim rect2Right As Double = rect2.Left + rect2.Width
Dim rect2Top As Double = rect2.Bottom + rect2.Height
Dim rect1Right As Double = rect1.Left + rect1.Width
Dim rect1Top As Double = rect1.Bottom + rect1.Height
If (rect2Right < rect1.Left OrElse rect2.Left > rect1Right) OrElse (rect2.Bottom > rect1Top OrElse rect2Top < rect1.Bottom) Then
Return RectangleF.Empty
End If
Dim left As Double = Math.Max(rect1.Left, rect2.Left)
Dim bottom As Double = Math.Max(rect1.Bottom, rect2.Bottom)
Dim width As Double = Math.Min(rect1Right, rect2Right) - left
Dim height As Double = Math.Min(rect1Top, rect2Top) - bottom
Dim x As Single = CSng((left - rect2.Left))
Dim y As Single = CSng(rect2.Height - (bottom + height - rect2.Bottom))
Dim rect As New RectangleF(x, y, CSng(width), CSng(height))
Return rect
End Function
The original page:
The edited page. The red cross lines appear when we use the trial version of PDFKit.