GithubHelp home page GithubHelp logo

ajaxray / markpdf Goto Github PK

View Code? Open in Web Editor NEW
159.0 10.0 31.0 39 KB

Watermark PDF files using image or text

License: GNU Affero General Public License v3.0

Shell 4.77% Go 95.23%
pdf watermark pdf-document cli utility developer-tools watermark-pdf-files

markpdf's Introduction

markpdf - Watermark PDF files using image or text

A tiny command line tool for watermarking PDF files using image or text. With simple options to configure position, opacity, rotation, stretch etc.

Highlights -

  • Very simple and easy to use
  • 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

It's just a single binary file, no external dependencies. Just download the appropriate version of executable from latest release for your OS. Then rename and give it execute permission.

mv markpdf_linux-amd64 markpdf  
sudo chmod +x markpdf

If you want to install it globally (run from any directory of your system), put it in your systems $PATH directory.

sudo mv markpdf /usr/local/bin/markpdf

Done!

How to use

Image watermarking

Command options are shown in both, shorthand and full name.

# watermark with all default options (on top left corner with 50% opacity)
markpdf "path/to/source.pdf" "img/logo.png" "path/to/output.pdf"

# watermark at center
markpdf "path/to/source.pdf" "img/logo.png" "path/to/output.pdf" --center
markpdf "path/to/source.pdf" "img/logo.png" "path/to/output.pdf" -c

# watermark at right top with 20px offset from edge and full opaque
markpdf "path/to/source.pdf" "img/logo.png" "path/to/output.pdf" --offset-x=-20 --offset-y=20 --opacity=1.0
markpdf "path/to/source.pdf" "img/logo.png" "path/to/output.pdf" -x -20 -y 20 -o 1.0

# watermark at left bottom with 100px offset and 45 degree rotation
markpdf "path/to/source.pdf" "img/logo.png" "path/to/output.pdf" --offset-x=100 --offset-y=-100 --angle=45
markpdf "path/to/source.pdf" "img/logo.png" "path/to/output.pdf" -x 100 -y -100 -a 45

# stretch full with of page at page middle, with 30% opacity
markpdf "path/to/source.pdf" "img/logo.png" "path/to/output.pdf" --scale-width-center --opacity=0.3
markpdf "path/to/source.pdf" "img/logo.png" "path/to/output.pdf" -Wo 0.3
# Note the capital "W" 

# 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

# watermark text at right top with 20px offset from edge
markpdf "path/to/source.pdf" "The Company Name" "path/to/output.pdf" --offset-x=-20 --offset-y=20
markpdf "path/to/source.pdf" "The Company Name" "path/to/output.pdf" -x -20 -y 20

# Place text at center with bold-italic "Times Roman" font in blue color
markpdf "path/to/source.pdf" "The Company Name" "path/to/output.pdf" --center --font=times_bold_italic --color=0000FF
markpdf "path/to/source.pdf" "The Company Name" "path/to/output.pdf" -cf times_bold_italic -l 0000FF

# Place text at center with large bold-italic "Times Roman" font in blue color
markpdf "path/to/source.pdf" "The Company Name" "path/to/output.pdf" --center --font=times_bold_italic --font-size=24.0 --color=0000FF
markpdf "path/to/source.pdf" "The Company Name" "path/to/output.pdf" -cf times_bold_italic -s 24.0 -l 0000FF

Using placeholders with text watermark

The following placeholder can be used in text watermark:

  • {{.Page}} prints the current page number
  • {{.Pages}} prints the total page numbers
  • {{.Filename}} prints name of the source file
# Using placeholders in text watermark
markpdf "path/to/083.pdf" "File: {{.Filename}} Page {{.Page}} of {{.Pages}}" "path/to/voucher_083.pdf" -x -20 -y 30

Allowed font identifiers

Currently the following font names are supported:

  • Courier: courier, courier_bold, courier_oblique, courier_bold_oblique
  • Helvetica: helvetica, helvetica_bold, helvetica_oblique, helvetica_bold_oblique
  • Times Roman: times, times_bold, times_italic, times_bold_italic

Additional notes

  • 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-*, --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 with your text and then use it for watermarking.

Roadmap

✅ Draw image on every page of PDF
✅ Configure Opacity option
✅ Configure watermark position by X and Y offset
✅ Allow negative values to for offset to adjust from opposite direction
✅️ Easy option for positioning image at center
✅ 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
✅ Render text on every page
✅ Configure text color, style and font
⏺ Configure text opacity
✅ Configure text rotation angle
✅ Text placement by offset
✅ Put text at page center

Contribute

If you fix a bug or want to add/improve a feature, and it's alligned with the focus of this tool - watermarking PDF with ease, I will be glad to accept your PR. :)

Thanks

This tool was made using the beautiful Unidoc library. Thanks and ❤️ to Unidoc.


"This is the Book about which there is no doubt, a guidance for those conscious of Allah" - Al-Quran

markpdf's People

Contributors

abellykens avatar ajaxray avatar ankurgel avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

markpdf's Issues

Compilation issue

As-Salamu Alaikum,

$ go build -ldflags=-s .

github.com/unidoc/unidoc/pdf/model

C:\Users\0wner\go\src\github.com\unidoc\unidoc\pdf\model\writer.go:538:12: constant 4294967295 overflows int

How do proceed?

Thanks in advance.

PDF properties?

Hi, first, thanks for a great utility! It's working great in testing so far.

Is there any scope for adding PDF properties, such as title, copyright, author etc?

Bus Error

Hi. Code works on my local but when i deploy it to my linux server i get a "Bus Error". Can't seem to find any more information around what's causing this.

Any ideas?

Image resolution

I would like to use a program to add a stamp. The stamp has a permanent dimension and rich content. Can you add the DPI option to the image? The standard is 72 DPI and the stamp is too big. If I give 144 DPI, the image will be two times smaller without losing quality. 300 DPI will add a small image with high resolution.

SVG file support

It would be nice to have the option to add watermark from a scalable format, like SVG.

Watermark position ignored

I specify -x -10 -y -10 as position to have watermark to the bottom right but with some pdf documents the tool doesn't respect the position specified and moves the watermark to the top right. Why does this happen?

Open source?

Hi,

You state that this is open source, but when I compiled this it required a unidoc dependency from Github. Although your built binaries work fine, when I compile it now, a watermark is added to the file from Unidoc and a license error is thrown.

I was trying to introduce a configuration option so that the watermark was only applied to the first page, but now this isn't possible.

Is this something you can revise?

In-document bookmarks and links are removed once marked with this tool

I have found that if I have a PDF document that has bookmarks and links for easy navigation, all of them are removed once I mark my PDF using this tool. Hope that a fix could be implemented so the marked PDF will preserve the bookmarks and links it originally contained. Thanks in advanced!

How to add new line in text placeholder?

I am trying to add 2 lines(rows or line break) placeholder. I am using php to call command and trying to add new line "\n".

It gives no error and also no placeholder added in pdf. If I remove new line chars it works but in one line.

Is there any way I can add 2 lines as text placeholder?

what about my code to support full page water mark

func drawText_offset(p *creator.Paragraph, c *creator.Creator, offsetX float64, offsetY float64, att *text_attributes) {
	// Change to times bold font (default is helvetica).
	p.SetFont(getFontByName(font))
	p.SetFontSize(att.FontSize)
	p.SetPos(offsetX, offsetY)
	p.SetColor(creator.ColorRGBFromHex("#" + att.FontColor))
	p.SetAngle(att.Angle)

	// Encountering problem with tiles and text watermark. Contributions welcome.
	//if tiles {
	//	repeatTiles(p, c)
	//	return
	//}

	_ = c.Draw(p)
}


func markPDF(inputPath string, outputPath string, watermark string) error {
	debugInfo(fmt.Sprintf("Input PDF: %v", inputPath))

	c := creator.New()
	var watermarkImg *creator.Image
	var para *creator.Paragraph

	isImageMark := isImageMark(watermark)
	watermarkIsATemplate := isWatermarkATemplate(watermark)

	// Read the input pdf file.
	f, err := os.Open(inputPath)
	fatalIfError(err, fmt.Sprintf("Failed to open the source file. [%s]", err))
	defer f.Close()

	pdfReader, err := pdf.NewPdfReader(f)
	fatalIfError(err, fmt.Sprintf("Failed to parse the source file. [%s]", err))

	numPages, err := pdfReader.GetNumPages()
	fatalIfError(err, fmt.Sprintf("Failed to get PageCount of the source file. [%s]", err))

	// Prepare data to insert into the template.
	rec := Recipient{
		Pages:    numPages,
		Filename: filepath.Base(inputPath[:len(inputPath)-len(filepath.Ext(inputPath))]),
	}
	var t *template.Template
	if !isImageMark && watermarkIsATemplate {
		t = template.Must(template.New("watermark").Parse(watermark))
	}

	for i := 0; i < numPages; i++ {
		pageNum := i + 1
		rec.Page = pageNum

		// Read the page.
		page, err := pdfReader.GetPage(pageNum)
		fatalIfError(err, fmt.Sprintf("Failed to read page from source. [%s]", err))

		// Add to creator.
		c.AddPage(page)

		// Calculate the position on first page
		if pageNum == 1 {
			debugInfo(fmt.Sprintf("Page Width       : %v", c.Context().PageWidth))
			debugInfo(fmt.Sprintf("Page Height      : %v", c.Context().PageHeight))
		}

		if isImageMark {
			if pageNum == 1 {
				watermarkImg, err = creator.NewImageFromFile(watermark)
				fatalIfError(err, fmt.Sprintf("Failed to load watermark image. [%s]", err))
				adjustImagePosition(watermarkImg, c)
			}

			drawImage(watermarkImg, c)

		}
		var need_draw_text = !isImageMark || full
		if need_draw_text {
			var attr text_attributes
			var text = watermark
			if full {
				attr.Alpha = float64(water_mark_config.Outdevconf.MaskConf.Alpha)
				attr.Angle = float64(water_mark_config.Outdevconf.MaskConf.Angle)
				attr.FontSize = float64(water_mark_config.Outdevconf.MaskConf.Fontsize)
				attr.FontColor = water_mark_config.Outdevconf.MaskConf.Fontcolor[1:]
				text = water_mark_config.Outdevconf.MaskText
			}
			if pageNum == 1 {
				para = creator.NewParagraph(text)
				adjustTextPosition(para, c)
			}

			if watermarkIsATemplate {
				applyTemplate(t, &rec, para)
			}
			if full {
				var gap_y = c.Context().PageHeight / 2
				var gap_x = c.Context().PageWidth / 4
				for x := 0; x < int(c.Context().PageWidth); x = x + int(gap_x) {
					for y := 0; y < int(c.Context().PageHeight); y = y + int(gap_y) {
						if x%2 == 0 {
							drawText_offset(para, c, float64(x), float64(y), &attr)
						} else {
							drawText_offset(para, c, float64(x), float64(y+int(gap_y)/2), &attr)
						}
					}
				}
			} else {
				drawText(para, c)
			}
		}
	}

	err = c.WriteToFile(outputPath)
	return err
}

Text Opacity not working like image opacity.

Hello @ajaxray ,

I'm using the command "markpdf "test_text.pdf" "Approved, Not published" "/var/www/html/test_text_out.pdf" -c -s 20.0 -a 45 -o 0.5" for add text as watermark, but the watermark is very dark. I also change opacity 0.1 but in both cases, the watermark looks the same.
test_text.pdf

But in the case of an image it's work fine.

Thank You In advance

Avira Security Alert

Hi,

I have a security problem running the program. I am using Windows 10 + Avira Free Security v1.1.57.24596.

Steps to reproduce:

  1. Download a release for Windows: Releases > markpdf_windows-386.exe
  2. Set appropriate execution permissions
  3. Run markpdf "path/to/source.pdf" "img/logo.png" "path/to/output.pdf"
  4. The popup below appears from Avira

image

MarkPDF working in terminal but not in Laravel > Process

Hi,

hopelly someone can help because this bug is driving me crazy.

Initially everything worked fine until few weeks ago.
I have updated markpdf with the latest version.

When i use process, the isSuccessful() returns true,
But the file is not modified.

When i use the exact same options as in process but paste this in the terminal.
Then the file is modified correctly.

This is driving me nuts because i can't make it to work with process and cant see any error messages.

Hopelly someone has an answer.

File need to be decrypted first

Hi,

The package was working fine, until today... Some of the PDF's can't be handled because i get this error message:

Output:\n================\nERROR: Failed to get PageCount of the source file. [File need to be decrypted first] \n\n\nError Output:\n================\n",

The PDF can be openend without password so i dont understand why it tells it has to be decrypted

Background color and Horizontal Center

Hi, thanks for this useful tool

Is there a way to set text background color?

And to center the watermark horizontally while defining a vertical offset (for instance, center at bottom of page)?

Thank you.

invalid media box causes output to be all blank

I have a PDF file that seems to have an invalid media box. The file opens fine using Adobe PDF reader, so I assume there's a standard default being used.

I can't provide the original file since it has sensitive information on it, and when I edit it, it "corrects" for the error.

I do I have a verbose output capture, and I can provide the output PDF.

markpdf bad.pdf "Test" bad_output.pdf --opacity=1 --font-size=12 --offset-x=10 --offset-y=10 -v
2023/01/03 14:30:05 Input PDF: bad.pdf
2023/01/03 14:30:05 No file exists at: Test, assuming Text Watermark.
[DEBUG]  parser.go:1530 Pdf version 1.7
[DEBUG]  main.go:131 Failed to get page mediabox: Invalid media box
2023/01/03 14:30:05 Page Width       : 0
2023/01/03 14:30:05 Page Height      : 0
2023/01/03 14:30:05 Paragraph width: 19.450000
2023/01/03 14:30:05 Paragraph height: 10.000000
2023/01/03 14:30:05 Offsets x: 10.000000, y: 10.000000

bad_output.pdf

I'll see if I can get the source code to work and hard-code some values and see if that makes a difference.

PDF I/O as base64

Will be good if we could have the possibility to use PDF base64 as input or in the output

Apple Silicon

Maybe I'm missing something, but is there a way to build this for Apple Silicon? I see the Darwin build, but it is not for ARM 64 as far as I can tell. Same goes for the build.sh. No way to build for Darwin + Arm

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.