Sample code for 30+ languages & platforms
SQL Server Requires Chilkat v11.7.0+

How a PDF Watermark Is Stored: artifact, annotation, layer or content

See more PDF Watermark Examples

Demonstrates the approach member, which decides how the watermark is stored and therefore what can be done with it afterwards. artifact (the default) is marked content that viewers draw, text extraction leaves out and Chilkat can remove later. annotation is a Watermark annotation, always on top, and the only approach allowed on a signed PDF while PreserveSignatures is true. layer is an optional-content layer the viewer can hide and that can be made print-only. content draws straight into the page with no marker: visible everywhere and the tamper-resistant choice, but by design it can never be listed or removed again.

Chilkat SQL Server Downloads

SQL Server
--
CREATE PROCEDURE ChilkatSample
AS
BEGIN
    DECLARE @hr int
    DECLARE @iTmp0 int
    DECLARE @sTmp0 nvarchar(4000)
    DECLARE @success int
    SELECT @success = 0

    --  This example requires the Chilkat API to have been previously unlocked.
    --  See Global Unlock Sample for sample code.

    --  The PDF used in this example is available at two_page_memo.pdf

    DECLARE @json int
    EXEC @hr = sp_OACreate 'Chilkat.JsonObject', @json OUT
    IF @hr <> 0
    BEGIN
        PRINT 'Failed to create ActiveX component'
        RETURN
    END

    DECLARE @jsonOut int
    EXEC @hr = sp_OACreate 'Chilkat.JsonObject', @jsonOut OUT

    DECLARE @filter int
    EXEC @hr = sp_OACreate 'Chilkat.JsonObject', @filter OUT

    --  The same watermark stored four different ways, each in its own copy of the document.
    DECLARE @pdf int
    EXEC @hr = sp_OACreate 'Chilkat.Pdf', @pdf OUT

    EXEC sp_OAMethod @pdf, 'LoadFile', @success OUT, 'qa_data/pdf/two_page_memo.pdf'
    IF @success = 0
      BEGIN
        EXEC sp_OAGetProperty @pdf, 'LastErrorText', @sTmp0 OUT
        PRINT @sTmp0
        EXEC @hr = sp_OADestroy @json
        EXEC @hr = sp_OADestroy @jsonOut
        EXEC @hr = sp_OADestroy @filter
        EXEC @hr = sp_OADestroy @pdf
        RETURN
      END

    EXEC sp_OAMethod @json, 'UpdateString', @success OUT, 'type', 'text'
    EXEC sp_OAMethod @json, 'UpdateString', @success OUT, 'text', 'DRAFT'
    EXEC sp_OAMethod @json, 'UpdateString', @success OUT, 'id', 'draft'
    EXEC sp_OAMethod @json, 'UpdateString', @success OUT, 'approach', 'artifact'
    EXEC sp_OAMethod @pdf, 'Watermark', @success OUT, 'add', @json, @jsonOut
    IF @success = 0
      BEGIN
        EXEC sp_OAGetProperty @pdf, 'LastErrorText', @sTmp0 OUT
        PRINT @sTmp0
        EXEC @hr = sp_OADestroy @json
        EXEC @hr = sp_OADestroy @jsonOut
        EXEC @hr = sp_OADestroy @filter
        EXEC @hr = sp_OADestroy @pdf
        RETURN
      END

    --  detect answers whether anything matching the filter is in the document.  Finding nothing is
    --  still success: "found" is simply false.
    EXEC sp_OAMethod @filter, 'UpdateString', @success OUT, 'id', 'draft'
    EXEC sp_OAMethod @pdf, 'Watermark', @success OUT, 'detect', @filter, @jsonOut
    IF @success = 0
      BEGIN
        EXEC sp_OAGetProperty @pdf, 'LastErrorText', @sTmp0 OUT
        PRINT @sTmp0
        EXEC @hr = sp_OADestroy @json
        EXEC @hr = sp_OADestroy @jsonOut
        EXEC @hr = sp_OADestroy @filter
        EXEC @hr = sp_OADestroy @pdf
        RETURN
      END

    EXEC sp_OAMethod @jsonOut, 'BoolOf', @iTmp0 OUT, 'found'
    PRINT 'artifact: found = ' + @iTmp0

    --  An annotation: always drawn on top, and the one approach a signed PDF accepts.
    DECLARE @pdf2 int
    EXEC @hr = sp_OACreate 'Chilkat.Pdf', @pdf2 OUT

    EXEC sp_OAMethod @pdf2, 'LoadFile', @success OUT, 'qa_data/pdf/two_page_memo.pdf'
    IF @success = 0
      BEGIN
        EXEC sp_OAGetProperty @pdf2, 'LastErrorText', @sTmp0 OUT
        PRINT @sTmp0
        EXEC @hr = sp_OADestroy @json
        EXEC @hr = sp_OADestroy @jsonOut
        EXEC @hr = sp_OADestroy @filter
        EXEC @hr = sp_OADestroy @pdf
        EXEC @hr = sp_OADestroy @pdf2
        RETURN
      END
    EXEC sp_OAMethod @json, 'UpdateString', @success OUT, 'approach', 'annotation'
    EXEC sp_OAMethod @pdf2, 'Watermark', @success OUT, 'add', @json, @jsonOut
    IF @success = 0
      BEGIN
        EXEC sp_OAGetProperty @pdf2, 'LastErrorText', @sTmp0 OUT
        PRINT @sTmp0
        EXEC @hr = sp_OADestroy @json
        EXEC @hr = sp_OADestroy @jsonOut
        EXEC @hr = sp_OADestroy @filter
        EXEC @hr = sp_OADestroy @pdf
        EXEC @hr = sp_OADestroy @pdf2
        RETURN
      END
    EXEC sp_OAMethod @pdf2, 'Watermark', @success OUT, 'detect', @filter, @jsonOut
    IF @success = 0
      BEGIN
        EXEC sp_OAGetProperty @pdf2, 'LastErrorText', @sTmp0 OUT
        PRINT @sTmp0
        EXEC @hr = sp_OADestroy @json
        EXEC @hr = sp_OADestroy @jsonOut
        EXEC @hr = sp_OADestroy @filter
        EXEC @hr = sp_OADestroy @pdf
        EXEC @hr = sp_OADestroy @pdf2
        RETURN
      END

    EXEC sp_OAMethod @jsonOut, 'BoolOf', @iTmp0 OUT, 'found'
    PRINT 'annotation: found = ' + @iTmp0

    --  A layer, which the viewer's layers panel can switch off.
    DECLARE @pdf3 int
    EXEC @hr = sp_OACreate 'Chilkat.Pdf', @pdf3 OUT

    EXEC sp_OAMethod @pdf3, 'LoadFile', @success OUT, 'qa_data/pdf/two_page_memo.pdf'
    IF @success = 0
      BEGIN
        EXEC sp_OAGetProperty @pdf3, 'LastErrorText', @sTmp0 OUT
        PRINT @sTmp0
        EXEC @hr = sp_OADestroy @json
        EXEC @hr = sp_OADestroy @jsonOut
        EXEC @hr = sp_OADestroy @filter
        EXEC @hr = sp_OADestroy @pdf
        EXEC @hr = sp_OADestroy @pdf2
        EXEC @hr = sp_OADestroy @pdf3
        RETURN
      END
    EXEC sp_OAMethod @json, 'UpdateString', @success OUT, 'approach', 'layer'
    EXEC sp_OAMethod @json, 'UpdateString', @success OUT, 'layer.name', 'Draft marking'
    EXEC sp_OAMethod @pdf3, 'Watermark', @success OUT, 'add', @json, @jsonOut
    IF @success = 0
      BEGIN
        EXEC sp_OAGetProperty @pdf3, 'LastErrorText', @sTmp0 OUT
        PRINT @sTmp0
        EXEC @hr = sp_OADestroy @json
        EXEC @hr = sp_OADestroy @jsonOut
        EXEC @hr = sp_OADestroy @filter
        EXEC @hr = sp_OADestroy @pdf
        EXEC @hr = sp_OADestroy @pdf2
        EXEC @hr = sp_OADestroy @pdf3
        RETURN
      END
    EXEC sp_OAMethod @pdf3, 'Watermark', @success OUT, 'detect', @filter, @jsonOut
    IF @success = 0
      BEGIN
        EXEC sp_OAGetProperty @pdf3, 'LastErrorText', @sTmp0 OUT
        PRINT @sTmp0
        EXEC @hr = sp_OADestroy @json
        EXEC @hr = sp_OADestroy @jsonOut
        EXEC @hr = sp_OADestroy @filter
        EXEC @hr = sp_OADestroy @pdf
        EXEC @hr = sp_OADestroy @pdf2
        EXEC @hr = sp_OADestroy @pdf3
        RETURN
      END

    EXEC sp_OAMethod @jsonOut, 'BoolOf', @iTmp0 OUT, 'found'
    PRINT 'layer: found = ' + @iTmp0

    --  Drawn into the page content with no marker.  There is nothing to find afterwards, which is the
    --  point of it: it cannot be stripped out by a tool that removes watermarks.
    DECLARE @pdf4 int
    EXEC @hr = sp_OACreate 'Chilkat.Pdf', @pdf4 OUT

    EXEC sp_OAMethod @pdf4, 'LoadFile', @success OUT, 'qa_data/pdf/two_page_memo.pdf'
    IF @success = 0
      BEGIN
        EXEC sp_OAGetProperty @pdf4, 'LastErrorText', @sTmp0 OUT
        PRINT @sTmp0
        EXEC @hr = sp_OADestroy @json
        EXEC @hr = sp_OADestroy @jsonOut
        EXEC @hr = sp_OADestroy @filter
        EXEC @hr = sp_OADestroy @pdf
        EXEC @hr = sp_OADestroy @pdf2
        EXEC @hr = sp_OADestroy @pdf3
        EXEC @hr = sp_OADestroy @pdf4
        RETURN
      END
    EXEC sp_OAMethod @json, 'UpdateString', @success OUT, 'approach', 'content'
    EXEC sp_OAMethod @pdf4, 'Watermark', @success OUT, 'add', @json, @jsonOut
    IF @success = 0
      BEGIN
        EXEC sp_OAGetProperty @pdf4, 'LastErrorText', @sTmp0 OUT
        PRINT @sTmp0
        EXEC @hr = sp_OADestroy @json
        EXEC @hr = sp_OADestroy @jsonOut
        EXEC @hr = sp_OADestroy @filter
        EXEC @hr = sp_OADestroy @pdf
        EXEC @hr = sp_OADestroy @pdf2
        EXEC @hr = sp_OADestroy @pdf3
        EXEC @hr = sp_OADestroy @pdf4
        RETURN
      END
    EXEC sp_OAMethod @pdf4, 'Watermark', @success OUT, 'detect', @filter, @jsonOut
    IF @success = 0
      BEGIN
        EXEC sp_OAGetProperty @pdf4, 'LastErrorText', @sTmp0 OUT
        PRINT @sTmp0
        EXEC @hr = sp_OADestroy @json
        EXEC @hr = sp_OADestroy @jsonOut
        EXEC @hr = sp_OADestroy @filter
        EXEC @hr = sp_OADestroy @pdf
        EXEC @hr = sp_OADestroy @pdf2
        EXEC @hr = sp_OADestroy @pdf3
        EXEC @hr = sp_OADestroy @pdf4
        RETURN
      END

    EXEC sp_OAMethod @jsonOut, 'BoolOf', @iTmp0 OUT, 'found'
    PRINT 'content: found = ' + @iTmp0

    --  Sample output:

    --  artifact: found = True
    --  annotation: found = True
    --  layer: found = True
    --  content: found = False

    EXEC @hr = sp_OADestroy @json
    EXEC @hr = sp_OADestroy @jsonOut
    EXEC @hr = sp_OADestroy @filter
    EXEC @hr = sp_OADestroy @pdf
    EXEC @hr = sp_OADestroy @pdf2
    EXEC @hr = sp_OADestroy @pdf3
    EXEC @hr = sp_OADestroy @pdf4


END
GO