Can I set saturation and luminosity while preserving hue in imagemagick? - colors

I'm tring to set the saturation and luminosity channels to a fixed value (100% saturation, 75% luinosity) on an image.
Following this I thought I'd use a evaluate - and this works ok:
convert input.png -colorspace HSL \
-channel B -evaluate multiply 0.80 \
-channel G -evaluate multiply 1.20 \
output.png
but doing this:
convert input.png -colorspace HSL \
-channel G -evaluate set 100 \
-channel B -evaluate set 50 \
output.png
results in a black image.
What am I doing wrong?

What am I doing wrong?
Your setting the channel data to a specific quantum value. A quantum value of 100 is about 1.5% if your working with ImageMagick Q16.
Ensure that the value ends with '%'
convert input.png -colorspace HSL \
-channel G -evaluate set 100% \
-channel B -evaluate set 50% \
output.png

#emcconville is correct. But I will add one more thing. Perhaps you also want to convert back to sRGB colorspace. So
convert lena.png -colorspace HSL \
-channel G -evaluate set 100% +channel \
-channel B -evaluate set 50% +channel \
-colorspace sRGB output2.png

Related

Calculating jpeg size from dimensions and bit depth

I have jpeg file with following details
ExampleJPEG File
The file size is 1342 bytes as shown above and also confirmed by Hex Editor.
I was thinking i could also calculate the file size by using its dimensions and bit depth.
i.e Total Bytes = ( Width X Height X bitDepth ) / 8
(28 X 28 X 24) / 8 = 2352 bytes
Why is this difference? The calculation formula says 2352 bytes whereas actual size is 1342 bytes. What am i missing?
When expanded out (decoded) and held as bytes in memory (RAM), the image will indeed occupy 2,352 bytes. But JPEGs are compressed to save space on disk, camera SD cards and when being Emailed and transmitted, so they are smaller and take less space/bandwidth.
If you want to see the pixel intensities in their expanded out RGB format, you can use a tool such as ImageMagick in the Terminal/command-line. Let's make a red image 28x28 - I'll make it in PNG format for now:
magick -size 28x28 xc:red PNG24:image.png
Now, if you want to view the pixels, you can either convert the image to a text dump with ImageMagick like this:
magick image.png -depth 8 -colorspace rgb txt:
Sample Output
# ImageMagick pixel enumeration: 28,28,65535,rgb
0,0: (255,0,0) #FF0000 rgb(255,0,0)
1,0: (255,0,0) #FF0000 rgb(255,0,0)
2,0: (255,0,0) #FF0000 rgb(255,0,0)
3,0: (255,0,0) #FF0000 rgb(255,0,0)
...
...
24,27: (255,0,0) #FF0000 rgb(255,0,0)
25,27: (255,0,0) #FF0000 rgb(255,0,0)
26,27: (255,0,0) #FF0000 rgb(255,0,0)
27,27: (255,0,0) #FF0000 rgb(255,0,0)
Or, if you want to view them in a more raw form of hex:
convert image.png -depth 8 rgb:image.raw
and view image.raw in a hex editor, or use Linux built-in tools:
convert image.png -depth 8 rgb: | xxd -g 3 -c12 | more
00000000: ff0000 ff0000 ff0000 ff0000 ............
0000000c: ff0000 ff0000 ff0000 ff0000 ............
00000018: ff0000 ff0000 ff0000 ff0000 ............
Note that if you check the size of the raw, uncompressed (decoded) image, you will see it happily matches your calculation of 2,352 bytes:
ls -l image.raw
-rw-r--r-- 1 mark staff 2352 27 Aug 09:56 image.raw
Note that I used PNG rather than JPEG above because JPEG is lossy and you don't get back what you save, you get something that looks similar but takes less space - like I said above.
Here is an example. I'll draw a red and a green line on a black background and save as a PNG and count the colours:
magick -size 100x100 xc:black +antialias -fill red -draw "line 5,5 95" -fill lime -draw "line 95,5 5,95" image.png
Now count the colours:
magick -format %k image.png info:
3
Now do exactly he same thing as a lossy JPEG:
magick -size 100x100 xc:black +antialias -fill red -draw "line 5,5 95,95" image.jpg
And count the colours in the JPEG and there are 148 now:
magick -format %k image.jpg info:
148
Keywords: Image Processing, ImageMagick, JPEG, lossy, PNG lossless, prime.

How to crop top and bottom border around my png with Gnuplot?

I have this script :
set title "df -m command test" font ",14"
set terminal pngcairo truecolor size 1600, 900 background rgb "#eff1f0" font "Arial"
set output "/usr/IBMAHS/htdocs/test.png"
set style line 1 \
linecolor rgb '#0060ad' \
linetype 1 linewidth 1 \
pointtype 7 pointsize 1
set style line 2 \
linecolor rgb "red" \
linetype 1 linewidth 1 \
pointtype 7 pointsize 1
set size ratio 0.2
set offsets 0.5,0.5,0,0.5
set key outside center
set datafile separator ","
set ylabel " MB BLOCK " font ",14" offset -1,0
set xlabel " Date " font ",14"
set xtics rotate by 45 offset -0.8,-1.8
set format y "%g"
myLabel(n) = sprintf("%g",n)
plot "/usr/IBMAHS/htdocs/TEST.txt" using 2:xtic(1) with linespoints linestyle 1 title "MB used", \
'' using 3:xtic(1) with linespoints linestyle 2 title " Free space ", \
'' using 0:2:(myLabel($2)) w labels offset 0,-0.5 notitle, \
'' using 0:3:(myLabel($3)) w labels offset 0,1 notitle
This script allow to generate this type of graph :
But the top and bottom border are so big... I would like to reduce them like that :
Can you show me how I can do this ?
You implicitely set the aspect ratio of your output graphic in the second line
set terminal pngcairo truecolor size 1600, 900 background rgb "#eff1f0" font "Arial"
Change the 900 to less to get the desired result.

Drawing a simple polygon using Gnuplot with "angle signs"

Disclaimer: I am new to Gnuplot, and I need to plot some "simple" things for my studies.
I want to plot a part of a polygon with some names and vectors added.
The picutre below was created with Euklid Dynageo, and I am now trying to create this with Gnuplot.
The biggest problem I am facing right now is the labeling u,v,w and adding the angles to the plot. I think I would use vectors and lines.
Do you now a 'simple' way to create this plot?
If you really need to use Gnuplot for this, you have to make it all manually by placing various objects, labels and arrows (keep in mind that complex plots will be cumbersome). A minimal example for two arrows and alpha_1, similar like in your example, could like like this:
# two arrows:
set arrow 1 from 0,0 to sqrt(2)/2,sqrt(2)/2
set arrow 2 from 0,0 to 1,0
# the alpha_1 symbol:
set label 1 '{/Symbol a}_1' at 0.2,0.1 front
# the filled yellow arc (from 0 to 45deg):
set style fill solid 1.0 border
set object 1 circle at 0,0 radius 0.2 arc[0:45] fc rgb "yellow"
# proper ratio, range, and plot 'something':
set xrange[-0.1:1.1]
set yrange[-0.1:1.1]
set size ratio 1
plot 1/0
Lookup the manual for possible object properties.
gnuplot is a very versatile plotting tool, but certainly not optimized for such tasks. For this type of drawing maybe Inkscape or others tools might be better choices, especially for interactive drawing by clicking, dragging and snapping.
And as #JackGlasshard already mentioned, of course you can do such graphs with gnuplot which will be rather time consuming if you do it manually.
Alternatively, you can facilitate the work if you use a "template".
Creating such a template probably only makes sense if you need to create more than one drawing.
Just for fun and feasibility, I tried to create such a template for general use to make such graphs easier.
For the input data you need 3 datablocks (without headers)
$Points: # no., x, y, label, xoff, yoff, pt, ps, color
you define: point number, x-coordinate, y-coordinate, point label, x-offset, y-offset, pointtype, pointsize, point color
$Vectors: # p1, p2, label, arrow, lw, dt, xoff, yoff, color
you define: first point number, second point number, label, arrowsstyle (-1=backhead, 0=nohead, 1=head, 2=heads), linewidth, dashtype, x-offset, y-offset, vector color
$Angles: # p1, p2, p3, r, label, aoff, roff, color
you define: 1st point number, 2nd point number (=angle center point), 3rd point number, radius, label, angular label offset, radial label offset, color
Now, you only have to change the data part of the script for your custom graph. In case you want to insert "invisible" vector starting or end points, simply set pointsize to 0 in $Points. The plotting of the variable arrowheads is a bit cumbersome because of the issue mentioned in this question.
For sure, more features and more flexibility can be added to the template. No warranty that the script is free of bugs. There is certainly room for improvements.
Update: (linewidth and dashtype added)
Since there is no variable linewidth (lw var) and no variable dashtype (dt var)
you have to plot each line separately in a for loop and every ::n::n.
Furthermore, I noticed that the order of variable pointsize (ps var) and and variable pointtype (pt var) apparently has changed from gnuplot 5.2 to 5.4. Not sure whether this intentional or a "bug".
The version below has the order for gnuplot 5.4.
Script:
### drawing sketch with points, vectors and angles
reset session
# no., x, y, label, xoff, yoff, pt, ps, color
$Points <<EOD
1 1 1 "" 0 0 5 1 0xff0000
2 10 2 V_{i-1} 0 0 5 1 0xff0000
3 15 10 V_i 0 0 5 1 0xff0000
4 4 12 X -1.5 0 5 1 0xff0000
5 14 16 V_{i+1} 0 0 5 1 0xff0000
6 5 20 "" 0 0 5 1 0xff0000
EOD
# p1, p2, label, arrow, lw, dt, xoff, yoff, color
# arrows: -1=backhead, 0=nohead, 1=head, 2=heads
$Vectors <<EOD
1 2 "" 0 1.0 1 0 0 0xff0000
2 3 "" 0 2.0 1 0 0 0x000000
3 5 "" 0 1.5 3 0 0 0x000000
4 2 w 1 1.0 1 1.0 0 0x000000
4 3 v 1 1.0 1 0 0.7 0x0000ff
4 5 u 1 1.0 1 0 0.7 0x000000
5 6 "" 0 1.0 1 0 0 0x000000
EOD
# p1, p2, p3, r, label, aoff, roff, color
# p2=angle center point
$Angles <<EOD
2 4 3 4.0 α_{i-1} 7.0 0.5 0xffcccc
3 4 5 4.5 α_i 3.0 0.7 0xffffcc
EOD
### end of data input
### start of template
# point/vector coordinates
px(n,m) = real(word($Points[int(word($Vectors[n],m))],2)) # x coordinate of point n
py(n,m) = real(word($Points[int(word($Vectors[n],m))],3)) # y coordinate of point n
vxd(n) = px(n,2)-px(n,1) # vector delta x
vyd(n) = py(n,2)-py(n,1) # vector delta y
vxc(n) = (px(n,2)+px(n,1))/2. # vector center x
vyc(n) = (py(n,2)+py(n,1))/2. # vector center y
lw(n) = real(word($Vectors[n],5))
dt(n) = int(word($Vectors[n],6))
# angles
as(n) = int(column(5)+2) # arrow style
ax(n) = real(word($Points[int(word($Angles[int(column(0)+1)],n))],2)) # angle center x
ay(n) = real(word($Points[int(word($Angles[int(column(0)+1)],n))],3)) # angle center y
set angle degrees
Angle(x0,y0,x1,y1) = (_dx=x1-x0, _dy=y1-y0, _L=sqrt(_dx**2 + _dy**2), _L==0 ? NaN : \
(_dy>=0 ? acos(_dx/_L) : -acos(_dx/_L) ))
a1(m) = Angle(ax(2),ay(2),ax(1),ay(1)) # starting angle
a2(m) = Angle(ax(2),ay(2),ax(3),ay(3)) # end angle
set style arrow 1 backhead filled # -1
set style arrow 2 nohead filled # 0
set style arrow 3 head filled # 1
set style arrow 4 heads filled # 2
set size ratio -1 # ensure same x- and y-ratio
set key noautotitle
set xrange [0:22]
set yrange [0:22]
set mxtics 5
set mytics 5
set grid x,y,mx,my
set style fill solid 0.5 border lc "black"
plot $Angles u (ax(2)):(ay(2)):4:(a1(0)):(a2(0)):8 w circles lc rgb var, \
'' u (ax(2)+($4*0.5+$7)*cos(0.5*(a1(0)+a2(0))+$6)): \
(ay(2)+($4*0.5+$7)*sin(0.5*(a1(0)+a2(0))+$6)):5 w labels font "Times New Roman,13" center, \
for [i=1:|$Vectors|] $Vectors \
u (px(i,1)):(py(i,1)):(vxd(i)):($4==-1?vyd(i):NaN):9 every ::i-1::i-1 w vectors lc rgb var lw lw(i) dt dt(i) filled backhead, \
for [i=1:|$Vectors|] '' \
u (px(i,1)):(py(i,1)):(vxd(i)):($4== 0?vyd(i):NaN):9 every ::i-1::i-1 w vectors lc rgb var lw lw(i) dt dt(i) filled nohead, \
for [i=1:|$Vectors|] '' \
u (px(i,1)):(py(i,1)):(vxd(i)):($4== 1?vyd(i):NaN):9 every ::i-1::i-1 w vectors lc rgb var lw lw(i) dt dt(i) filled head, \
for [i=1:|$Vectors|] '' \
u (px(i,1)):(py(i,1)):(vxd(i)):($4== 2?vyd(i):NaN):9 every ::i-1::i-1 w vectors lc rgb var lw lw(i) dt dt(i) filled heads, \
for [i=1:|$Vectors|] '' \
u (vxc(i)+$7):(vyc(i)+$8):3:9 every ::i-1::i-1 w labels font ",12" tc rgb var, \
$Points u 2:3:7:8:9 w p ps var pt var lc rgb var, \
'' u ($2+$5):($3+$6):4:9 w labels tc rgb var font ",12" left offset 1,0
### end of script
Result:

Gnuplot Plot a Candlesticks plot, but use a line inside the key?

I'm using a C++ program to automate a lot of plots with Gnuplot. I am making boxplots using the candlestick plot style, and I add median and mean by adding modified candlestick plots, based on the example in the manual:
plot ’stat.dat’ using 1:3:2:6:5 with candlesticks title ’Quartiles’, \
’’ using 1:4:4:4:4 with candlesticks lt -1 notitle
This works, but the key looks funny, because the Mean and Median are drawn as rectangles in the key, even though they appear as lines on the plot. Here is an example:
Is there an easy way to make the key display lines instead of rectangles?
Possible solutions could include plotting the mean and median as lines instead of candlesticks, but I would need to calculate the X positions of each start and stop point. Another solution could include drawing the key manaually using labels and lines. But these could be complex and not very flexible, so I'd thought to ask if any simpler solutions exist.
You can fake key entries by plotting "invisible" lines:
set terminal pngcairo
set output "candle_lines.png"
set boxwidth 0.4 relative
set xrange [0:4]
set yrange [0:100]
plot 'stat.dat' using 1:3:2:6:5 with candlesticks title 'Quartiles', \
'' using 1:4:4:4:4 with candlesticks lt -1 notitle, \
'' using 1:7:7:7:7 with candlesticks lt 0 notitle, \
NaN with lines title "Mean" lt -1, \
NaN with lines title "Median" lt 0
My stat.dat:
1 40 50 63 65 70 57
2 50 60 67 75 80 63
3 30 40 53 55 60 47
The result:

Inexplicable color difference of two images created with imagemagick (convert + montage)

I am in the process of creating several images, containing text and diagrams, using imagemagick and other tools.
At some point I realized that, even though the same instructions were being used in batch with little changes, the colors - defined very precisely by their hex value - change from image to image!
Here is an example (no input file needed) that gives reproduceably wrong (or at least unexpected) results on my machine (Ubuntu 14.04, ImageMagick 6.7.7-10 2017-07-31) [edited per fmw42's suggestion]
convert -size 66x46 -bordercolor "#a0a0a0" -border 2 xc:White -gravity Center -fill "#a0a0a0" -weight 700 -pointsize 24 -annotate 0 "0" a_1.png
convert -size 326x46 -bordercolor "#f0f0f0" -border 2 xc:White -gravity West -fill "#000000" -weight 700 -pointsize 14 -annotate +10+0 "4-Fluoroacetophenone" a_2.png
montage -colorspace sRGB a_1.png a_2.png -tile 2x1 -mode Concatenate -set colorspace sRGB a_3.png
convert -size 66x46 -bordercolor "#a0a0a0" -border 2 xc:White -gravity Center -fill "#a0a0a0" -weight 700 -pointsize 24 -annotate 0 "CN" b_1.png
convert -size 326x46 -bordercolor "#f0f0f0" -border 2 xc:White -gravity West -fill "#000000" -weight 700 -pointsize 14 -annotate +10+0 "trans-3-dimethylaminoacrylonitrile" b_2.png
montage -colorspace sRGB b_1.png b_2.png -tile 2x1 -mode Concatenate -set colorspace sRGB b_3.png
(I have left the original text variables, since I haven't been able to understand what triggers the change of color, and different rendered words give different results)
The 6 istructions above create these 6 images:
a_1.png a_2.png a_3.png
b_1.png b_2.png b_3.png
that appear like this:
As you can see, while a_1 and b_1 share the same color - and a_2 and b_2 as well - a_3 and b_3 (which are composite of a_1+a_2 and b_1+b_2) have different colors! Having added explicit specification of colorspace hasn't helped.
(This is not an artifact of having put the 6 pictures in a single file. The color difference is apparent in the separate files as well)
What is causing this? How can I get consistent colors in imagemagick? As I'm using visual color codes to convey information, I need palettes that I can rely on.
Edit: this does't happen (i.e. colors are consistent) with ImageMagick 6.8.9-9 Q16 x86_64 2017-07-31 that unfortunately isn't the version I have on my production machine.
I'm not removing the question as finding a solution within ImageMagick 6.7.7 would help. Or is it just a (known) bug and so the only solution is upgrading?
Your ImageMagick 6.7.7-10 2017-07-31 has been patched numerous times and the latest patch was 2017-07-31. There have been reports of other issues with the patch. So I suspect it had a bad patch and you should inquire of your Linux distribution.
Note that proper Imagemagick syntax for raster images is to read the input image first (or create it) before any settings and operators. So properly, your syntax should be
convert -size 66x46 xc:White -bordercolor "#a0a0a0" -border 2 -gravity Center -fill "#a0a0a0" -weight 700 -pointsize 24 -annotate 0 "0" a_1.png
IM 6 is forgiving, so it likely will not matter. But IM 7 is not as forgiving.
The -set colorspace sRGB is likely un-necessary in your command, but should not hurt. But if used, should be properly placed after creating your input image.
Using Imagemagick 6.9.9.5 Q16 Mac OSX (2017-08-04) and Imagemagick 7.0.6.5 Q16 HDRI, proper syntax should be:
IM 6
convert -size 66x46 xc:White -bordercolor "#a0a0a0" -border 2 -gravity Center -fill "#a0a0a0" -weight 700 -pointsize 24 -annotate 0 "0" a_1.png
convert -size 326x46 xc:White -bordercolor "#f0f0f0" -border 2 -gravity West -fill "#000000" -weight 700 -pointsize 14 -annotate +10+0 "4-Fluoroacetophenone" a_2.png
montage a_1.png a_2.png -tile 2x1 -mode Concatenate -set colorspace sRGB a_3.png
convert -size 66x46 xc:White -bordercolor "#a0a0a0" -border 2 -gravity Center -fill "#a0a0a0" -weight 700 -pointsize 24 -annotate 0 "CN" b_1.png
convert -size 326x46 xc:White -bordercolor "#f0f0f0" -border 2 -gravity West -fill "#000000" -weight 700 -pointsize 14 -annotate +10+0 "trans-3-dimethylaminoacrylonitrile" b_2.png
montage b_1.png b_2.png -tile 2x1 -mode Concatenate -set colorspace sRGB b_3.png
IM 7
magick -size 66x46 xc:White -bordercolor "#a0a0a0" -border 2 -gravity Center -fill "#a0a0a0" -weight 700 -pointsize 24 -annotate 0 "0" a_1.png
magick -size 326x46 xc:White -bordercolor "#f0f0f0" -border 2 -gravity West -fill "#000000" -weight 700 -pointsize 14 -annotate +10+0 "4-Fluoroacetophenone" a_2.png
magick montage -colorspace sRGB a_1.png a_2.png -tile 2x1 -mode Concatenate -set colorspace sRGB a_3.png
magick -size 66x46 xc:White -bordercolor "#a0a0a0" -border 2 -gravity Center -fill "#a0a0a0" -weight 700 -pointsize 24 -annotate 0 "CN" b_1.png
magick -size 326x46 xc:White -bordercolor "#f0f0f0" -border 2 -gravity West -fill "#000000" -weight 700 -pointsize 14 -annotate +10+0 "trans-3-dimethylaminoacrylonitrile" b_2.png
magick montage -colorspace sRGB b_1.png b_2.png -tile 2x1 -mode Concatenate -set colorspace sRGB b_3.png
For both I get:
Is this correct? Do you get something different using my commands?

Resources