diff --git a/go.mod b/go.mod index 0b62c8d0..96aea4b9 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/unidoc/globalsign-dss v0.0.0-20220330092912-b69d85b63736 github.com/unidoc/pkcs7 v0.2.0 github.com/unidoc/unichart v0.3.0 - github.com/unidoc/unipdf/v3 v3.62.0 + github.com/unidoc/unipdf/v3 v3.65.0 golang.org/x/crypto v0.31.0 golang.org/x/image v0.18.0 golang.org/x/text v0.21.0 @@ -50,7 +50,7 @@ require ( github.com/unidoc/timestamp v0.0.0-20200412005513-91597fd3793a // indirect github.com/unidoc/unitype v0.4.0 // indirect go.opencensus.io v0.24.0 // indirect - golang.org/x/net v0.24.0 // indirect + golang.org/x/net v0.33.0 // indirect golang.org/x/oauth2 v0.7.0 // indirect golang.org/x/sys v0.28.0 // indirect golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect diff --git a/go.sum b/go.sum index d4f465c8..be365d03 100644 --- a/go.sum +++ b/go.sum @@ -128,8 +128,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.3.0 h1:VX1j5yzhjrR3f2flC03Yat6/WF3h7Z+DLEvJLoTGhoc= github.com/unidoc/unichart v0.3.0/go.mod h1:8JnLNKSOl8yQt1jXewNgYFHhFm5M6/ZiaydncFDpakA= -github.com/unidoc/unipdf/v3 v3.62.0 h1:CVsxq6k1SSIrprotlFvq6iBhA+5745dWaApB0LKtGcc= -github.com/unidoc/unipdf/v3 v3.62.0/go.mod h1:0OIzSHHno23Y8WzaK+852abK8d3AxUZ1GQkMqpyCzu8= +github.com/unidoc/unipdf/v3 v3.65.0 h1:ye3PP9JuUJnQd4BqRR4wJO/EN9EpHRGusMOruDjCS74= +github.com/unidoc/unipdf/v3 v3.65.0/go.mod h1:tTbloOTKtGGi6z5doJshesDpQYktePhR+7r+WGCkooU= github.com/unidoc/unitype v0.4.0 h1:/TMZ3wgwfWWX64mU5x2O9no9UmoBqYCB089LYYqHyQQ= github.com/unidoc/unitype v0.4.0/go.mod h1:HV5zuUeqMKA4QgYQq3KDlJY/P96XF90BQB+6czK6LVA= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= @@ -153,8 +153,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= -golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= +golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= +golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.7.0 h1:qe6s0zUXlPX80/dITx3440hWZ7GwMwgDDyrSGTPJG/g= golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4= diff --git a/image/README.md b/image/README.md index 2d1ad981..b6bfb402 100644 --- a/image/README.md +++ b/image/README.md @@ -9,4 +9,5 @@ Having the ability to play around with images allows for the creation of attract - [pdf_images_to_pdf.go](pdf_images_to_pdf.go) explains how to add multiple images in a PDF document, one image per page. - [pdf_list_images.go](pdf_list_images.go) explains how to list images in a PDF file. Passes through each page, goes through the content stream and finds instances of both. XObject Images and inline images. Also handles images referred within XObject Form content streams. - [pdf_watermark_image.go](pdf_watermark_image.go) explains how to add watermark image to each page of a PDF file. +- [pdf_remove_watermark_image.go](pdf_remove_watermark_image.go) explains how to remove watermark image from a PDF file. - Image extraction example can be found in [../extract](extract) example subfolder. diff --git a/image/pdf_remove_watermark_image.go b/image/pdf_remove_watermark_image.go new file mode 100644 index 00000000..30cde34d --- /dev/null +++ b/image/pdf_remove_watermark_image.go @@ -0,0 +1,81 @@ +/* + * Remove watermark image to each page of a PDF file. + * + * Run as: go run pdf_remove_watermark_image.go input.pdf output.pdf + */ + +package main + +import ( + "fmt" + "os" + + "github.com/unidoc/unipdf/v3/common/license" + "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_remove_watermark_image.go input.pdf output.pdf\n") + os.Exit(1) + } + + inputPath := os.Args[1] + outputPath := os.Args[2] + + pdfReader, f, err := model.NewPdfReaderFromFile(inputPath, nil) + if err != nil { + fmt.Printf("Error: %v\n", err) + os.Exit(1) + } + defer f.Close() + + numPages, err := pdfReader.GetNumPages() + if err != nil { + fmt.Printf("Error: %v\n", err) + os.Exit(1) + } + + for i := 0; i < numPages; i++ { + pageNum := i + 1 + + // Read the page. + page, err := pdfReader.GetPage(pageNum) + if err != nil { + fmt.Printf("Error: %v\n", err) + os.Exit(1) + } + + // For watermarks applied by Adobe, just pass nil as argument. + // For custom watermarks use pdf_list_images.go to figure out the name of watermark object. + err = page.RemoveWatermarkImage("Img1") + if err != nil { + fmt.Printf("Error: %v\n", err) + os.Exit(1) + } + } + + // Generate a PDFWriter from PDFReader. + pdfWriter, err := pdfReader.ToWriter(nil) + if err != nil { + fmt.Printf("Error: %v\n", err) + os.Exit(1) + } + + err = pdfWriter.WriteToFile(outputPath) + if err != nil { + fmt.Printf("Error: %v\n", err) + os.Exit(1) + } + + fmt.Printf("Complete, see output file: %s\n", outputPath) +} diff --git a/image/pdf_watermark_image.go b/image/pdf_watermark_image.go index 0bff352f..313b9a23 100644 --- a/image/pdf_watermark_image.go +++ b/image/pdf_watermark_image.go @@ -8,11 +8,11 @@ package main import ( "fmt" + "image" "os" "github.com/unidoc/unipdf/v3/common" "github.com/unidoc/unipdf/v3/common/license" - "github.com/unidoc/unipdf/v3/creator" "github.com/unidoc/unipdf/v3/model" ) @@ -49,13 +49,25 @@ func addWatermarkImage(inputPath string, outputPath string, watermarkPath string common.Log.Debug("Input PDF: %v", inputPath) common.Log.Debug("Watermark image: %s", watermarkPath) - c := creator.New() + // Create the watermark image from file. + wImgFile, err := os.Open(watermarkPath) + if err != nil { + return err + } + defer wImgFile.Close() + + watermarkImg, _, err := image.Decode(wImgFile) + if err != nil { + return err + } - watermarkImg, err := c.NewImageFromFile(watermarkPath) + image, err := model.DefaultImageHandler{}.NewImageFromGoImage(watermarkImg) if err != nil { return err } + xImage, err := model.NewXObjectImageFromImage(image, nil, nil) + // Read the input pdf file. f, err := os.Open(inputPath) if err != nil { @@ -82,21 +94,19 @@ func addWatermarkImage(inputPath string, outputPath string, watermarkPath string return err } - // Add to creator. - c.AddPage(page) - - watermarkImg.ScaleToWidth(c.Context().PageWidth) - watermarkImg.SetPos(0, (c.Context().PageHeight-watermarkImg.Height())/2) - watermarkImg.SetOpacity(0.5) - _ = c.Draw(watermarkImg) + // Add watermark with options. + page.AddWatermarkImage(xImage, model.WatermarkImageOptions{Alpha: 0.5, FitToWidth: true}) } - // Add reader outline tree to the creator. - c.SetOutlineTree(pdfReader.GetOutlineTree()) - - // Add reader AcroForm to the creator. - c.SetForms(pdfReader.AcroForm) + // Generate a PDFWriter from PDFReader. + pdfWriter, err := pdfReader.ToWriter(nil) + if err != nil { + return err + } - err = c.WriteToFile(outputPath) - return err + err = pdfWriter.WriteToFile(outputPath) + if err != nil { + return err + } + return nil }