invisible-watermark icon indicating copy to clipboard operation
invisible-watermark copied to clipboard

CLI decode doesn't work if output image is JPG

Open TheNemus opened this issue 1 year ago • 2 comments

I'm trying to use as CLI and python script to generate a wmrked JPG but watermark decode doesn't show anything:

C:\Users\me\AppData\Local\Programs\Python\Python310\Scripts>py invisible-watermark "F:\JPEG\_DSC5341.jpg" -v -a encode -t bytes -m dwtDct -w '1234' -o "F:\JPEG\_DSC5341-w.jpg"
watermark length: 48
encode time ms: 2819.3318843841553

C:\Users\me\AppData\Local\Programs\Python\Python310\Scripts>py invisible-watermark "F:\JPEG\_DSC5341-w.jpg" -v -a decode -t bytes -m dwtDct -l 48
decode time ms: 1944.9546337127686

It's like there is no watermark impressed in it, unless I use a PNG as output. I posted the images I'm using for test purpouses.

raw img test wm img test_wm

TheNemus avatar Oct 13 '22 10:10 TheNemus

Same here but this works:

  1. output a png which has the drawback of being several times bigger than the jpg original
  2. compress the png any way you want
  3. using ImageMagick, convert the png into a jpg; it is much smaller now but still bigger than the original
  4. Now, when decoding the jpg, it works and outputs the original watermark text -- that is weird because if you do not go thru the intermediate steps of the png but encode straight to a jpg it does NOT work
  5. Of course, if you convert the resulting jpg into a png again, it works too...

asitemade4u avatar Feb 13 '23 14:02 asitemade4u

The problem seems to come from the default jpeg subsampling used by OpenCV. I was able to solve the problem by disabling subsampling. The resulting file was about 2.5 times bigger than the original file. By decreasing JPEG quality to 90% (default: 95) and activating jpeg optimize, I was able to reduce the filesize to ~1.5 times the original file.

[…]
encoder = WatermarkEncoder()
encoder.set_watermark('bytes', wm.encode('utf-8'))
img_encoded = encoder.encode(img, 'dwtDct')

encode_param = [
#    int(cv2.IMWRITE_JPEG_QUALITY), 90,
#    int(cv2.IMWRITE_JPEG_OPTIMIZE), 1,
    int(cv2.IMWRITE_JPEG_SAMPLING_FACTOR), cv2.IMWRITE_JPEG_SAMPLING_FACTOR_444,
]
cv2.imwrite("/tmp/image.jpg", img_encoded, encode_param)

Further information: https://docs.opencv.org/3.4/d8/d6a/group__imgcodecs__flags.html#gga292d81be8d76901bff7988d18d2b42aca2cf91496164f00416064e7b8ac12981a https://docs.opencv.org/3.4/d8/d6a/group__imgcodecs__flags.html#ga4b97ca569a53587801257896d79656e1

sighalt avatar Feb 27 '23 11:02 sighalt