Skip to content

Commit

Permalink
[UP-450] Ink annotation example (#225)
Browse files Browse the repository at this point in the history
* add example code

* use paths instead of points

* update dependencies
  • Loading branch information
3ace authored Jun 5, 2023
1 parent 76e6895 commit 267949e
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 3 deletions.
1 change: 1 addition & 0 deletions annotations/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ The examples in this folder illustrate a few capabilities for creating ellipse,
## Examples

- [pdf_annotate_add_ellipse.go](pdf_annotate_add_ellipse.go) adds a circle/ellipse annotation to a specified location on a page.
- [pdf_annotate_add_ink.go](pdf_annotate_add_ink.go) adds an ink annotation to a specified location on a page.
- [pdf_annotate_add_line.go](pdf_annotate_add_line.go) adds a line with arrowhead between two specified points on a page.
- [pdf_annotate_add_rectangle.go](pdf_annotate_add_rectangle.go) adds a rectangle annotation to a specified location on a page.
- [pdf_annotate_add_text.go](pdf_annotate_add_text.go) adds a text annotation with a user specified string to a fixed location on every page.
Expand Down
137 changes: 137 additions & 0 deletions annotations/pdf_annotate_add_ink.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
/*
* Annotate/mark up pages of a PDF file.
* Add an ink annotation with shape of a checkmark on a page.
*
* Run as: go run pdf_annotate_add_ink.go input.pdf output.pdf
*/

package main

import (
"fmt"
"os"
"time"

"github.com/unidoc/unipdf/v3/annotator"
"github.com/unidoc/unipdf/v3/common/license"
"github.com/unidoc/unipdf/v3/contentstream/draw"
"github.com/unidoc/unipdf/v3/core"
"github.com/unidoc/unipdf/v3/model"
)

func init() {
// Make sure to load your metered License API key prior to using the library.
// If you need a key, you can sign up and create a free one at https://cloud.unidoc.io
err := license.SetMeteredKey(os.Getenv(`UNIDOC_LICENSE_API_KEY`))
if err != nil {
panic(err)
}
}

func main() {
if len(os.Args) < 3 {
fmt.Printf("go run pdf_annotate_add_ink.go input.pdf output.pdf\n")
os.Exit(1)
}

inputPath := os.Args[1]
outputPath := os.Args[2]

paths := []draw.Path{
{
Points: []draw.Point{
draw.NewPoint(361.019, 638.415),
draw.NewPoint(361.488, 637.946),
draw.NewPoint(363.361, 635.605),
draw.NewPoint(365.233, 632.796),
draw.NewPoint(368.043, 629.518),
draw.NewPoint(371.321, 625.772),
draw.NewPoint(373.662, 622.494),
draw.NewPoint(375.535, 620.621),
draw.NewPoint(376.471, 619.216),
draw.NewPoint(376.94, 618.28),
draw.NewPoint(377.408, 618.28),
draw.NewPoint(377.876, 618.748),
draw.NewPoint(379.281, 621.089),
draw.NewPoint(382.09, 627.177),
draw.NewPoint(386.305, 636.073),
draw.NewPoint(390.987, 646.843),
draw.NewPoint(395.201, 655.272),
draw.NewPoint(397.543, 660.891),
draw.NewPoint(398.947, 664.168),
draw.NewPoint(399.884, 666.041),
draw.NewPoint(400.352, 666.51),
},
},
}

err := annotatePdfAddInk(inputPath, outputPath, paths)
if err != nil {
fmt.Printf("Error: %v\n", err)
os.Exit(1)
}

fmt.Printf("Complete, see output file: %s\n", outputPath)
}

// Annotate pdf file.
func annotatePdfAddInk(inputPath string, outputPath string, paths []draw.Path) error {
// Read the input pdf file.
f, err := os.Open(inputPath)
if err != nil {
return err
}
defer f.Close()

pdfReader, err := model.NewPdfReader(f)
if err != nil {
return err
}

// Process each page using the following callback
// when generating PdfWriter.
opt := &model.ReaderToWriterOpts{
PageProcessCallback: func(pageNum int, page *model.PdfPage) error {
inkAnnot, err := annotator.CreateInkAnnotation(annotator.InkAnnotationDef{
Paths: paths,
Color: model.NewPdfColorDeviceRGB(0.89, 0.13, 0.21),
})
if err != nil {
return err
}

switch t := inkAnnot.GetContext().(type) {
case *model.PdfAnnotationInk:
t.T = core.MakeName("InkAnnot")

creationDate, err := model.NewPdfDateFromTime(time.Now())
if err != nil {
return err
}

t.CreationDate = creationDate.ToPdfObject()
t.M = creationDate.ToPdfObject()
t.P = page.ToPdfObject()
}

// Add to the page annotations.
page.AddAnnotation(inkAnnot)

return nil
},
}

// Generate a PdfWriter instance from existing PdfReader.
pdfWriter, err := pdfReader.ToWriter(opt)
if err != nil {
return err
}

// Write to file.
err = pdfWriter.WriteToFile(outputPath)
if err != nil {
return err
}

return nil
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ require (
github.com/unidoc/globalsign-dss v0.0.0-20220330092912-b69d85b63736
github.com/unidoc/pkcs7 v0.1.1-0.20220329190817-dd59b9eba14c
github.com/unidoc/unichart v0.1.0
github.com/unidoc/unipdf/v3 v3.45.0
github.com/unidoc/unipdf/v3 v3.46.0
github.com/wcharczuk/go-chart/v2 v2.1.0
go.opencensus.io v0.24.0 // indirect
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -403,8 +403,8 @@ github.com/unidoc/timestamp v0.0.0-20200412005513-91597fd3793a h1:RLtvUhe4DsUDl6
github.com/unidoc/timestamp v0.0.0-20200412005513-91597fd3793a/go.mod h1:j+qMWZVpZFTvDey3zxUkSgPJZEX33tDgU/QIA0IzCUw=
github.com/unidoc/unichart v0.1.0 h1:GoJ/rxSoOYZsqlG3yOJpKkwgfsIQgb9hHX7bILZHcCg=
github.com/unidoc/unichart v0.1.0/go.mod h1:9sJXeqxIIsU2D07tmhpDMoND0mBFRGfKBJnXZMsJnzk=
github.com/unidoc/unipdf/v3 v3.45.0 h1:ao7sWfB04ZLvWit5SSem0N/01pZxStoVxorH8nhCnJk=
github.com/unidoc/unipdf/v3 v3.45.0/go.mod h1:g42g9gaGCT2hLoNK+r/RZdNVnvhF1X6qx6wpTKJwg2E=
github.com/unidoc/unipdf/v3 v3.46.0 h1:FjYaPgHPt2Guk7KeRsFnxbR9Ftp0qZsVaif0+lu8/f0=
github.com/unidoc/unipdf/v3 v3.46.0/go.mod h1:g42g9gaGCT2hLoNK+r/RZdNVnvhF1X6qx6wpTKJwg2E=
github.com/unidoc/unitype v0.2.1 h1:x0jMn7pB/tNrjEVjy3Ukpxo++HOBQaTCXcTYFA6BH3w=
github.com/unidoc/unitype v0.2.1/go.mod h1:mafyug7zYmDOusqa7G0dJV45qp4b6TDAN+pHN7ZUIBU=
github.com/wcharczuk/go-chart/v2 v2.1.0 h1:tY2slqVQ6bN+yHSnDYwZebLQFkphK4WNrVwnt7CJZ2I=
Expand Down

0 comments on commit 267949e

Please sign in to comment.