diff --git a/README.md b/README.md index a66f01d..ee47e39 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,8 @@ Highlights - - Extreamly fast! - Stretching watermark image to height or weight proportionately - Options to adjust position, opacity, rotation of image +- Placeholder for text watermark +- Tile image watermark all over the page - Free and open source ## Install @@ -56,7 +58,17 @@ markpdf "path/to/source.pdf" "img/logo.png" "path/to/output.pdf" -Wo 0.3 # stretch full with of page at page bottom markpdf "path/to/source.pdf" "img/logo.png" "path/to/output.pdf" --scale-width --offset-y=-10 markpdf "path/to/source.pdf" "img/logo.png" "path/to/output.pdf" -wy -10 -``` + +# Scale the image to desired percentage +markpdf "path/to/source.pdf" "img/logo.png" "path/to/output.pdf" --scale=30 + +# Add image as tiles all over the page +markpdf "path/to/source.pdf" "img/logo.png" "path/to/output.pdf" --tiles + +# Add image as tiles with interleaved spacing +markpdf "path/to/source.pdf" "img/logo.png" "path/to/output.pdf" --tiles --spacing=20 +`` + ### Text watermarking @@ -83,11 +95,9 @@ The following placeholder can be used in text watermark: ```bash # Using placeholders in text watermark -markpdf "path/to/083.pdf" "File: {{.Filename}} Page {{.Page}} of {{.Pages}}" "path/to/voucher_083.pdf" --position=10,-10 +markpdf "path/to/083.pdf" "File: {{.Filename}} Page {{.Page}} of {{.Pages}}" "path/to/voucher_083.pdf" -x -20 -y 30 ``` -_Note: This (placeholder) feature will be available in upcoming release. If you want to use it right now, please build from the `master` branch._ - #### Allowed font identifiers Currently the following font names are supported: @@ -100,7 +110,7 @@ Currently the following font names are supported: - **Specifying Colors**: write them as 6 or 3 digit hexadecilal as used in CSS, without the # - `--color`, `--font` and `--font-size` flag has no impact for Image watermarking -- `--scale-*` and `--opacity` flag has no impact for Text watermarking +- `--scale-*`, `--tiles` and `--opacity` flag has no impact for Text watermarking - Negative offset will set content positioning from opposite side (right for offsetX and botom from offsetY) - Text with opacity is not supported at this moment. Instead, you can [create a transperent background PNG image](http://www.picturetopeople.org/text_generator/others/transparent/transparent-text-generator.html) with your text and then use it for watermarking. @@ -114,10 +124,10 @@ Currently the following font names are supported: ✅ Configure image rotation angle ✅ Options to Stretch watermark to page width or height, proportionately ✅ Options to Stretch watermark to page width or height at the middle of page -◻️ Tile Image all over the page +✅ Tile Image all over the page ✅ Render text on every page ✅ Configure text color, style and font -◻️ Configure text opacity +⏺ Configure text opacity ✅ Configure text rotation angle ✅ Text placement by offset ✅ Put text at page center diff --git a/build.sh b/build.sh old mode 100644 new mode 100755 index 36fef8a..ca6268b --- a/build.sh +++ b/build.sh @@ -1,5 +1,14 @@ -env GOOS=darwin GOARCH=amd64 go build -ldflags="-s -w" -o builds/markpdf_darwin-amd64 +env GOOS=darwin GOARCH=amd64 go build -ldflags="-s -w" -o builds/markpdf_darwin-amd64 +upx builds/markpdf_darwin-amd64 + +env GOOS=darwin GOARCH=arm64 go build -ldflags="-s -w" -o builds/markpdf_darwin-arm64 +# upx is not working properly for Mac M1 Build :( + env GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o builds/markpdf_linux-amd64 +upx builds/markpdf_linux-amd64 + env GOOS=linux GOARCH=arm64 go build -ldflags="-s -w" -o builds/markpdf_linux-arm64 +upx builds/markpdf_linux-arm64 + env GOOS=windows GOARCH=386 go build -ldflags="-s -w" -o builds/markpdf_windows-386.exe -upx builds/markpdf_* \ No newline at end of file +upx builds/markpdf_windows-386.exe diff --git a/img_watermark.go b/img_watermark.go index 008c005..54c482e 100644 --- a/img_watermark.go +++ b/img_watermark.go @@ -8,9 +8,13 @@ import ( ) func drawImage(watermarkImg *creator.Image, c *creator.Creator) { - watermarkImg.SetPos(offsetX, offsetY) watermarkImg.SetOpacity(opacity) watermarkImg.SetAngle(angle) + if tiles { + repeatTiles(watermarkImg, c) + return + } + watermarkImg.SetPos(offsetX, offsetY) _ = c.Draw(watermarkImg) } @@ -20,9 +24,13 @@ func adjustImagePosition(watermarkImg *creator.Image, c *creator.Creator) { if scaleImage != 100 { - debugInfo(fmt.Sprintf("Scaling to %v", scaleImage)) + debugInfo(fmt.Sprintf("Scaling to %v%%", scaleImage)) watermarkImg.ScaleToHeight(scaleImage * watermarkImg.Width() / 100) } + if tiles { + offsetX, offsetY = 0, 0 + return + } if scaleWCenter { watermarkImg.ScaleToWidth(c.Context().PageWidth) offsetX = 0 diff --git a/main.go b/main.go index 8cb9e8e..96079a0 100644 --- a/main.go +++ b/main.go @@ -2,17 +2,18 @@ package main import ( "fmt" + "os" + "path/filepath" + "text/template" + flag "github.com/ogier/pflag" unicommon "github.com/unidoc/unidoc/common" "github.com/unidoc/unidoc/pdf/creator" pdf "github.com/unidoc/unidoc/pdf/model" - "os" - "path/filepath" - "text/template" ) -var offsetX, offsetY, scaleImage, fontSize float64 -var scaleH, scaleW, scaleHCenter, scaleWCenter, center, verbose, version bool +var offsetX, offsetY, scaleImage, fontSize, spacing float64 +var scaleH, scaleW, scaleHCenter, scaleWCenter, center, tiles, verbose, version bool var opacity, angle float64 var font, color string @@ -37,18 +38,21 @@ func init() { flag.Float64VarP(&opacity, "opacity", "o", 0.5, "Opacity of watermark. float between 0 to 1.") flag.Float64VarP(&angle, "angle", "a", 0, "Angle of rotation. between 0 to 360, counter clock-wise.") + flag.BoolVarP(&tiles, "tiles", "t", false, "Repeat watermark as tiles on page. All offsets will be ignored.") + flag.Float64VarP(&spacing, "spacing", "z", 0, "Repeat watermark as tiles on page. All offsets will be ignored.") + flag.BoolVarP(&verbose, "verbose", "v", false, "Display debug information.") flag.BoolVarP(&version, "version", "V", false, "Display Version information.") flag.Usage = func() { - fmt.Println("markpdf [options...]") + fmt.Println("Usages: markpdf [options...]") fmt.Println(" and should be path to a PDF file and can be a text or path of an image.") - fmt.Println("text can be used with the following variable:") - fmt.Println("{{.Page}} current page number") - fmt.Println("{{.Pages}} total page numbers") - fmt.Println("{{.Filename}} source file name") - fmt.Println("Example: markpdf \"path/to/083.pdf\" \"img/logo.png\" \"path/to/voucher_083.pdf\" --position=10,-10 --opacity=0.4") + fmt.Println("") + fmt.Println("Example: markpdf \"path/to/083.pdf\" \"img/logo.png\" \"path/to/voucher_083.pdf\" -x 10 -y -30 --opacity=0.5") + fmt.Println("Example: markpdf \"path/to/083.pdf\" \"img/logo.png\" \"path/to/tmp_voucher_083.pdf\" --tiles --spacing=50 --opacity=0.2") + fmt.Println("Example: markpdf \"path/to/083.pdf\" \"GreatCompanyName\" \"path/to/voucher_083.pdf\" -cf times_bold_italic") fmt.Println("Example: markpdf \"path/to/083.pdf\" \"File: {{.Filename}} Page {{.Page}} of {{.Pages}}\" \"path/to/voucher_083.pdf\" --position=10,-10 --opacity=0.4") + fmt.Println("") fmt.Println("Available Options: ") flag.PrintDefaults() } diff --git a/text_watermark.go b/text_watermark.go index 9fae5e7..e9d61aa 100644 --- a/text_watermark.go +++ b/text_watermark.go @@ -24,6 +24,12 @@ func drawText(p *creator.Paragraph, c *creator.Creator) { p.SetColor(creator.ColorRGBFromHex("#" + color)) p.SetAngle(angle) + // Encountering problem with tiles and text watermark. Contributions welcome. + //if tiles { + // repeatTiles(p, c) + // return + //} + _ = c.Draw(p) } @@ -31,7 +37,11 @@ func adjustTextPosition(p *creator.Paragraph, c *creator.Creator) { p.SetTextAlignment(creator.TextAlignmentLeft) p.SetEnableWrap(false) - if center { + if tiles { + p.SetWidth(p.Width()) // Not working without setting it manually + p.SetTextAlignment(creator.TextAlignmentCenter) + offsetX, offsetY = 0, 0 + } else if center { p.SetWidth(p.Width()) // Not working without setting it manually p.SetTextAlignment(creator.TextAlignmentCenter) diff --git a/tiles.go b/tiles.go new file mode 100644 index 0000000..801eea1 --- /dev/null +++ b/tiles.go @@ -0,0 +1,36 @@ +package main + +import ( + "fmt" + "github.com/unidoc/unidoc/pdf/creator" + "math" +) + +// Watermarkable is a common interface for watermarkable image or paragraph +type Watermarkable interface { + creator.VectorDrawable + SetPos(x, y float64) +} + +func repeatTiles(watermark Watermarkable, c *creator.Creator) { + w := watermark.Width() + h := watermark.Height() + pw := c.Context().PageWidth + ph := c.Context().PageHeight + + nw := math.Ceil(pw / w) + nh := math.Ceil(ph / h) + + debugInfo(fmt.Sprintf("Settings tiles of %v x %v", nw, nh)) + for i := 0; i < int(nw); i++ { + x := w * float64(i) + for j := 0; j < int(nh); j++ { + y := h * float64(j) + watermark.SetPos(x + spacing * float64(i), y + spacing * float64(j)) + err := c.Draw(watermark) + if err != nil { + fatalIfError(err, fmt.Sprintf("Error %s", err)) + } + } + } +}