Dynamic image watermarking - injecting model attributes into watermarks - ruby-on-rails
I'm currently using this Paperclip::Processor to watermark images with imagemagick's composite command.
It allows me to inject a pre-made single file as a watermark, which lives in my public file.
However, I'm trying to work out if it's possible to modify this to dynamically generate watermarks that include model attributes. For example, the watermark includes the name of a photographer, or the model of the camera it has been taken with.
Getty have recently changed their watermark to do just this - it's very clever, and I'm fascinated to know how they've done it.
Many thanks in advance. I'm not expecting people to know exactly how to do this, but any ideas or general principles would be appreciated.
Yes it can be done with Imagemagick; I have done it with php and a batch script. I have no idea how you would convert this batch script into ruby-on-rails though.
You can get most values contained in the EXIF data and use them in some similar code to this.
:: Do not display the code while running
#ECHO OFF
:: Select the F number from the EXIF data and set the FNumber variable
FOR /F %%x IN ('identify -ping -format "%%[EXIF:FNumber]" %1') DO SET FNumber=%%x
:: Set the FNumber1 variable to the F number value
:: Image Magick returns the F number in the format of 700/100 or 40/10
FOR /F %%x IN ('convert xc: -ping -format "%%[fx:%FNumber%]" info:') DO SET FNumber1=%%x
:: Set the value of the shutter variable to the shutter speed
:: Select the shutter speed from the EXIF data
:: Image Magick returns the shutter speed in the format of 810/100
FOR /F %%x IN ('identify -ping -format "%%[EXIF:ShutterSpeedValue]" %1') DO SET shutter=%%x
:: Format the speed to 8.1 and set the speed variable
FOR /F %%x IN ('convert xc: -ping -format "%%[fx:%shutter%]" info:') DO SET speed=%%x
:: Calculate the speed in seconds using the power of 2
:: and save it in the shutterspeed variable
FOR /F %%x IN ('convert xc: -ping -format "%%[fx:floor((pow(2,%speed%)))]" info:') ^
DO SET shutterspeed=%%x
:: Add the F number and shutter speed to the image
:: and save as exif_OriginalImageName
convert %INPUTFILE% ^
-pointsize 16 -fill black -gravity northwest ^
-annotate +10+5 "Aperture: F%FNumber1% Shutter speed: 1/%shutterspeed% sec" "%~p1EXIF_%~n1.jpg"
Thanks for your help Beerlington. I actually worked out a way of doing this by adding convert_options to the image during the paperclip thumbnailing process. So, on the image model, where a is the image:
has_attached_file :image,
processors: [:thumbnail],
styles: {
wide: {
geometry: "1120x",
convert_options: ->(a) { "-quality 92 -font Arial -pointsize 72 -gravity center gradient: -alpha on -channel rgba -fill 'rgba(255,255,255,0.3)' -opaque 'rgba(20,20,20,1)' -draw \"text 0, 340 #{a.picusername}\" -pointsize 30 -draw \"text 0, 390 'license copy here'\"
"}
}
This writes a.picusername on the image with various placement and styling details. You can find more of these here.
A final note - If you are adding attributes to the image model using something like simpleform, the above processing instructions are applied at the instant the image itself is added to the db... so any model attributes added after the image attachement (literally, in the form inputs below the image attach) will not be recognised, as they don't yet exist.
Related
Convert image from one format to another sent to STDOUT
I'd like to convert an image from .jpg to .png. This works just fine: convert input.jpg output.png But, I'm trying to have my output go to STDOUT instead of a file, which the manual says to use "-". I tried using: convert input.jpg -.png But it just creates a file called -.png. Is it possible to convert an image from one format to another and have it go to STDOUT?
Yes, just use a command like this to convert a JPEG to a PNG on stdout: magick input.jpg PNG:- These specifiers work on input as well as output. So, if you have a TIFF on stdin and want a 32-bit RGBA PNG on stdout: magick TIFF:- PNG32:- You often need these specifiers to ensure a specific filetype when it is not explicitly given, or you want to use a different extension. So, say you have some CCD device that produces RGB data in a raw binary file called image.bin and you want ImageMagick to read it. You can tell ImageMagick the format without having to change the filename (to image.rgb) like this: magick -size WxH RGB:image.bin result.png The possible formats are documented here. The king of all of these formats is MIFF which is guaranteed to be able to hold any and all things you might throw at it, including floating-point values, transparency, masks, concatenated streams... so if you need a format to pass between ImageMagick commands, MIFF is a good option. An example, just to demonstrate because it is not optimal, might to be to concatenate two images from 2 separate ImageMagick commands into a third command that makes an animated GIF: { magick -size 100x60 xc:red miff:- ; magick -size 100x60 xc:blue miff:- ; } | magick -delay 80 miff:- result.gif
Imagemagick: How to get image width, then use that to batch resize all images in folder to width x width / 2?
I have over 400 images I need resizing. They need to be their individual original widths, but the heights need to be exactly half the width of each image. I've been trying for 3 hours to get something work in Imagemagick, with no luck. Any ideas? Thanks a lot! magick 40inch_downbelow_001.jpg -ping -resize "x%w/2" 40inch_downbelow_0aaaaaaa01.jpg - This is my current command, which is just a test. This spits out an image of exactly the same size, despite telling it to use half the width.
Here are two ways to accomplish this in Windows, one using ImageMagick v6 and another using v7. These will run all the JPG images in a directory. Using IMv6... for %I in ( *.jpg ) do ( convert "%I" -set filename:0 "%[t]XXX.%[e]" ^ +distort SRT "0,0 1,%[fx:w/h/2] 0" -shave 1 "%[filename:0]" ) Using IMv7... for %I in ( *.jpg ) do ( magick "%I" -set filename:0 "%[t]XXX.%[e]" -resize "x%[fx:w/2]!" "%[filename:0]" ) Substitute your file name modifier for the "XXX" I used in the examples. To use these commands in a BAT script you'll need to double the percent signs "%%".
I think you want this, for a single image: magick input.png -resize "x%[fx:int(w/2)]\!" result.png The fact there is nothing before the x means the width is left unchanged. The new height is calculated as half the width and the exclamation mark permits distortion of the original aspect ratio. If you want to do all PNGs in the current directory, use: #!/bin/bash for f in *.png; do magick "$f" -resize "x${h}\!" "$f" done If you only have old, v6 ImageMagick, go with: #!/bin/bash for f in *.png; do # Get current width and halve it w=$(identify -format "%w" "$f") ((h=w/2)) mogrify -resize x${h}\! "$f" done
imagemagick - Restrict elaboration to a region of the image
I need to process a large amount of scans of dot matrix printed documents in order to optimize them for reading with an ocr engine. I used imagemagick to make sure that there are no white spaces between the points of the matrix, so the ocr engine works much better. The problem is performance, pdfs are scanned at 600dpi and processing takes too long. I would like to limit the processing only to the area affected by the zonal ocr, I tried with the "-region" operator but even if it works, the processing takes the same time. This is the command used by the windows command line: convert -density "601.6x600" -units pixelsperinch -monochrome files\1.pdf -region 2000x200+2500+2100 -negate -morphology Thinning "17x17+8+8: -,-,-,-,-,0,0,0,0,0,0,0,-,-,-,-,- -,-,-,-,0,0,0,0,0,0,0,0,0,-,-,-,- -,-,-,0,0,0,0,0,0,0,0,0,0,0,-,-,- -,-,0,0,0,0,-,-,-,-,-,0,0,0,0,-,- -,0,0,0,0,-,-,-,-,-,-,-,0,0,0,0,- 0,0,0,0,-,-,-,-,-,-,-,-,-,0,0,0,0 0,0,0,-,-,-,-,-,-,-,-,-,-,-,0,0,0 0,0,0,-,-,-,-,-,-,-,-,-,-,-,0,0,0 0,0,0,-,-,-,-,-,1,-,-,-,-,-,0,0,0 0,0,0,-,-,-,-,-,-,-,-,-,-,-,0,0,0 0,0,0,-,-,-,-,-,-,-,-,-,-,-,0,0,0 0,0,0,0,-,-,-,-,-,-,-,-,-,0,0,0,0 -,0,0,0,0,-,-,-,-,-,-,-,0,0,0,0,- -,-,0,0,0,0,-,-,-,-,-,0,0,0,0,-,- -,-,-,0,0,0,0,0,0,0,0,0,0,0,-,-,- -,-,-,-,0,0,0,0,0,0,0,0,0,-,-,-,- -,-,-,-,-,0,0,0,0,0,0,0,-,-,-,-,-" -morphology Thinning "13x13+6+6: -,-,0,0,0,0,0,0,0,0,0,-,- -,0,0,0,0,0,0,0,0,0,0,0,- 0,0,0,-,-,-,-,-,-,-,0,0,0 0,0,-,-,-,-,-,-,-,-,-,0,0 0,0,-,-,-,-,-,-,-,-,-,0,0 0,0,-,-,-,-,-,-,-,-,-,0,0 0,0,-,-,-,-,1,-,-,-,-,0,0 0,0,-,-,-,-,-,-,-,-,-,0,0 0,0,-,-,-,-,-,-,-,-,-,0,0 0,0,-,-,-,-,-,-,-,-,-,0,0 0,0,0,-,-,-,-,-,-,-,0,0,0 -,0,0,0,0,0,0,0,0,0,0,0,- -,-,0,0,0,0,0,0,0,0,0,-,-" -morphology Close Disk -negate -compress zip r.pdf P.S. I wanted to post on the imagemagick forum, but I didn't find the link to subscribe ...
Issue is resolved here https://github.com/ImageMagick/ImageMagick/discussions/2841. the -region param appears to act after the processing of entire file. Fixed using clone, crop, layer and flatten: magick in.tiff ( +clone -crop 100x100+500+500 -morphology dilate disk ) -layers flatten x2.tiff
Multiple resize operations in ImageMagick
I'm trying to combine some operations using ImageMagick's magick CLI, specifically two operations that resize/scale the image, a random one that does -resize and a bunch of other stuff, plus the answer from this question (Average image color excluding transparency with Imagemagick). The naive "mix everything together" doesn't work: magick image -resize 10x10 ... -scale 1x1! -alpha off -format "%[pixel:u.p]\n" info: ...as I get an answer of "black", because this is obviously ignoring my image and using a blank image instead. I've also tried with subimages (using \( ... \)) but that has the same problem
The following command works fine for me on ImageMagick 6.9.10.16 Q16. What is your ImageMagick version and what other commands do you need in the command line. You only show ...! What else is there? Also can you post your image? You cannot just put "image" in your command line. You have to specify the actual image file and possibly the path to it. Input: convert logo.png -transparent white -resize 50% -scale 1x1! -alpha off -format "%[pixel:u.p]" info: srgb(100,82,99) Same with IM 7.0.8.16 Q16 HDRI: magick logo.png -transparent white -resize 50% -scale 1x1! -alpha off -format "%[pixel:u.p]" info: srgb(100,81,99) The slight difference is likely a difference from precision with IM 6 (non-hdri) and IM 7 (with hydra).
Extracting data digitally
I have 200 copies of this page(15 * 10 matrix) and i have to write all the numbers from 0 - 9 in each corresponding cell and then extract those digits digitally in a seperate image of (32*32 pixels) for each digit, after scanning each page once. How can i achieve this? This is required for my research purpose. I am a CS student so i can code too. Update: For mark : Here is one of the scanned image This is for some local language ( 0 - 9) .. Update 2: The commands for the previous image are working fine but on new images,something is getting wrong(some kind of offsets).. I am attaching the image below What changes do u suggest ?
Updated Answer I have taken your feedback and improved the algorithm to the following bash script now... #!/bin/bash ################################################################################ # dice # # Trim borders off an image (twice) and then dice into 10x15 cells. # # Usage: ./dice image ################################################################################ # Pick up image name from first parameter image="$1" echo DEBUG: Processing image $image... # Apply median filter to remove noisy black dots around image and then get the # dimensions of the "trim box" - note we don't use the (degraded) median-filtered image in # later steps. trimbox=$(convert "$image" -median 9x9 -fuzz 50% -format %# info:) echo DEBUG: trimbox $trimbox # Now trim original unfiltered image into stage1-$$.png (for debug) convert "$1" -crop $trimbox +repage stage1-$$.png echo DEBUG: Trimmed outer: stage1-$$.png # Now trim column headings convert stage1-$$.png -crop 2000x2590+120+190 +repage stage2-$$.png echo DEBUG: Trimmed inner: stage2-$$.png # Now slice into 10x15 rectangles echo DEBUG: Slicing and dicing convert stage2-$$.png -crop 10x15# +repage rectangles-%03d.png # Now trim the edges off the rectangles and resize all to a constant size for f in rectangles*png; do echo DEBUG: Trimming and resizing $f trimbox=$(convert "$f" -median 9x9 -shave 15x15 -bordercolor black -border 15 -threshold 50% -floodfill +0+0 white -fuzz 50% -format %# info:) echo DEBUG: Cell trimbox $trimbox convert "$f" -crop $trimbox +repage -resize 32x32! "$f" done Here are the resulting cells - i.e. 150 separate image files. I have put a red border around the individual cells/files so you can see their extent: Original Answer I would do that with ImageMagick which is free and installed on most Linux distros and is available for OSX and Windows too. There are Perl, PHP, Java, node, .NET, Ruby, C/C++ bindings too if you prefer those languages. Here I am using the command line in Terminal. First job is to get rid of noise and trim the outer edges: convert scan.jpg -median 3x3 -fuzz 50% -trim +repage trimmed1.png Now, trim again to get rid of outer frame and column titles across the top: convert trimmed1.png -crop 2000x2590+120+190 +repage trimmed2.png Now divide into 10 cells by 15 cells and save as rectangles-nnn.png convert trimmed2.png -crop 10x15# rectangles-%03d.png Check what we got - yes, 150 images: ls -l rect* rectangles-000.png rectangles-022.png rectangles-044.png rectangles-066.png rectangles-088.png rectangles-110.png rectangles-132.png rectangles-001.png rectangles-023.png rectangles-045.png rectangles-067.png rectangles-089.png rectangles-111.png rectangles-133.png rectangles-002.png rectangles-024.png rectangles-046.png rectangles-068.png rectangles-090.png rectangles-112.png rectangles-134.png rectangles-003.png rectangles-025.png rectangles-047.png rectangles-069.png rectangles-091.png rectangles-113.png rectangles-135.png rectangles-004.png rectangles-026.png rectangles-048.png rectangles-070.png rectangles-092.png rectangles-114.png rectangles-136.png rectangles-005.png rectangles-027.png rectangles-049.png rectangles-071.png rectangles-093.png rectangles-115.png rectangles-137.png rectangles-006.png rectangles-028.png rectangles-050.png rectangles-072.png rectangles-094.png rectangles-116.png rectangles-138.png rectangles-007.png rectangles-029.png rectangles-051.png rectangles-073.png rectangles-095.png rectangles-117.png rectangles-139.png rectangles-008.png rectangles-030.png rectangles-052.png rectangles-074.png rectangles-096.png rectangles-118.png rectangles-140.png rectangles-009.png rectangles-031.png rectangles-053.png rectangles-075.png rectangles-097.png rectangles-119.png rectangles-141.png rectangles-010.png rectangles-032.png rectangles-054.png rectangles-076.png rectangles-098.png rectangles-120.png rectangles-142.png rectangles-011.png rectangles-033.png rectangles-055.png rectangles-077.png rectangles-099.png rectangles-121.png rectangles-143.png rectangles-012.png rectangles-034.png rectangles-056.png rectangles-078.png rectangles-100.png rectangles-122.png rectangles-144.png rectangles-013.png rectangles-035.png rectangles-057.png rectangles-079.png rectangles-101.png rectangles-123.png rectangles-145.png rectangles-014.png rectangles-036.png rectangles-058.png rectangles-080.png rectangles-102.png rectangles-124.png rectangles-146.png rectangles-015.png rectangles-037.png rectangles-059.png rectangles-081.png rectangles-103.png rectangles-125.png rectangles-147.png rectangles-016.png rectangles-038.png rectangles-060.png rectangles-082.png rectangles-104.png rectangles-126.png rectangles-148.png rectangles-017.png rectangles-039.png rectangles-061.png rectangles-083.png rectangles-105.png rectangles-127.png rectangles-149.png rectangles-018.png rectangles-040.png rectangles-062.png rectangles-084.png rectangles-106.png rectangles-128.png rectangles-019.png rectangles-041.png rectangles-063.png rectangles-085.png rectangles-107.png rectangles-129.png rectangles-020.png rectangles-042.png rectangles-064.png rectangles-086.png rectangles-108.png rectangles-130.png rectangles-021.png rectangles-043.png rectangles-065.png rectangles-087.png rectangles-109.png rectangles-131.png Look at first couple: You can do those 3 steps in 1 like this: convert scan.jpg -median 3x3 -fuzz 50% -trim +repage \ -crop 2000x2590+120+190 +repage \ -crop 10x15# rectangles-%03d.png You may want to shave a few pixels off each side of each image and resize to 32x32 with something like (untested): mogrify -shave 3x3 -resize 32x32! rectangles*png