I need a truly random BMP in order to test various lossy image compression algorithms. Ideally, this would not rely on any library and run in a Linux CLI.
It should generate a random BMP given a certain width and height.
Updated Answer - April 2021
Here are some more ideas for random images:
Random coloured squares
magick -size 8x8 xc: +noise Random -scale 100x100 RandomColouredSquares.png
Random black and white crosswords
magick -size 8x8 xc:gray +noise Random -threshold 50% -scale 100x100 RandomCrosswords.png
Random grey blur
magick -size 8x8 xc:gray +noise Random -resize 100x100 RandomGreyBlur.png
Random coloured blur
magick -size 5x5 xc: +noise Random -auto-level -resize 100x100 RandomColouredBlur.png
Random salt and pepper
magick -size 100x100 xc:gray +noise Random -threshold 1% -negate RandomSaltAndPepper.png
Repeated coloured pattern
magick -size 50x50 xc: +noise random -virtual-pixel tile -blur 0x6 -auto-level -write MPR:tile +delete -size 250x250 tile:MPR:tile RandomRepeatedPattern.png
Updated Answer - March 2021
If you want random-noise type of images, see original answer below, noting that you should replace convert with magick in those examples if working with ImageMagick v7 onwards.
If you want images of a solid random colour, you could do something like this:
magick -size 400x200 xc:"rgb($((RANDOM%255)),$((RANDOM%255)),$((RANDOM%255)))" image.png
Sample Outputs
If you want images of a random size and a random solid colour, you could use this for images between 200..264 pixels wide by 100..132 pixels tall:
magick -size "$(((RANDOM%64)+200))x$(((RANDOM%32)+100))" xc:"rgb($((RANDOM%255)),$((RANDOM%255)),$((RANDOM%255)))"random.png
Sample Outputs
Original Answer
You can use ImageMagick (which is installed on most Linux distros by default) to generate an image of random noise like this:
convert -size 300x200 xc:gray +noise random out.bmp
where 300 is the width and 200 is the height (just examples).
Other types of noise are available, just run
convert -list noise
Output
Gaussian
Impulse
Laplacian
Multiplicative
Poisson
Random
Uniform
If the noise is too noisy ;-) for you, you can attenuate it with
convert -size 300x200 xc:gray -attenuate 0.5 +noise random out.bmp
for a 50% attenuation
Here are some examples of the different types:
Here are the corresponding distribution histograms:
Just for completeness, note that this answer features in Daniel Barrett's book "Efficient Linux at the Command Line".
Related
I'm using ImageMagick to trim some PDFs of text that I've converted to jpg for a project. In most cases it works well but when the page has just a small amount of text, say half a sentence, trim works too well so the image is just that, half a sentence.
It's a problem as it causes some display issues where I'm presenting it so it'd be helpful if there was a minimum image size. Is there a way of doing that in ImageMagick? Or adding padding to an image if it is converted below a certain size?
This is the command I'm using:
convert '*.jpeg' -fuzz 1% -trim +repage -set filename:base "%[basename]" "%[filename:base].jpg"
I'm using ImageMagick 7.1.0-19 Q16-HDRI arm 2021-12-22
Currently there is no way that I can think that would limit the trim in that way in Imagemagick. But you can automatically pad the image with some color such as white to some minimum size.
However, you will need to use "magick" in place of "convert" for Imagemagick 7 to make it work properly.
Input (256x256):
Lets pad it with white to 100x100 (minimum)
magick image.png -fuzz 1% -trim +repage -gravity center -bordercolor white -border "%[fx:w<100?round(0.5*(100-w)):0]x%[fx:h<100?round(0.5*(100-h)):0]" result.png
or better
magick input.png -fuzz 1% -trim +repage -gravity center -background white -extent "%[fx:w<100?100:w]x%[fx:h<100?100:h]" result.png
I had the exact same question recently, and the answer was to combine -trim and -extent.
convert -trim -background none -gravity center -extent 1024x1024 input.png output.webp
The image will first be trimmed, then extended to a given size.
You might want to change -gravity and -background depending on your use case.
I need a 256 pixels color palette because FFmpeg gives me this error:
Palette input must contain exactly 256 pixels.
I use ImageMagick on Mac OS to create a GIF palette from an image that contains a few shades of grey so I don't need that large color palette. The way Palettegen generates palette is it takes a number of max colors, for example, max_colors=8 and fills the rest 248 pixels with black. I want to do the same with convert.
Is there a way to specify max colors number in ImageMagick convert and fill rest of the 256 color palette with black?
You can do that rather easily in ImageMagick (for 8 grays) by creating a 256x1 black image and compositing your 8 gray shades from your image onto it at the beginning.
convert \( -size 256x1 xc:black \) \( image -colorspace gray -dither none -colors 8 -unique-colors \) -compose over -composite colormap.gif
I have an image with nearly smooth background with some extra lines on it. I want to convert the image from RGB color space to LAB color space and then average the "L" part of pixels.
But before converting I want to delete extra lines or somehow ignore lines pixels in averaging the "L" part. Is there any algorithm to do this?
Below is an example of the images I have.
An option is to compute the gradient (Sobel for instance) and avoid doing the accumulation where the gradient magnitude is significant.
Following the comment by #Paul, it will be interesting to see the influence of the threshold level on the computed average.
I am using ImageMagick like your other question.
This will give you a mask of all the pixels that differ by more than 5% from their surrounding area (it's the 0.05 in the -fx part). It works by loading the stone image, copying it and blurring the copy to remove local details. It then calculates the absolute difference between the original and the blurred copy and sets the pixel to 1 if the difference exceeds 5% else sets it to 0:
convert stone.jpg -colorspace gray \( +clone -blur x10 \) -fx "abs(u-v)>0.05?1:0" mask.png
Experiment with changing the 0.05 and see what you think.
This will tell you how many pixels in the mask are white. It relies on the mean being sum of pixel brightnesses divided by number of pixels and knowing all pixels are either 0 or 1:
convert mask.png -format "%[fx:int(mean*w*h)]" info:
6155
This will blacken all the masked pixels. It works by loading both the stone and the mask, inverting the mask and then, at each pixel position, choosing the darker of the two images - so it will choose black everywhere the mask is white and it will choose the stone everywhere else:
convert stone.jpg \( mask.png -negate \) -compose darken -composite nolines.png
In ImageMagick, if you make the pixels to be ignored transparent, you can get the average of all non-transparent pixels using -scale 1x1!. For example, from the two images above:
So first put the mask into the alpha channel, then scale the result to one pixel, turn alpha off and get the pixel color:
convert image.jpg mask.png -alpha off -compose copy_opacity -composite -scale 1x1! -alpha off -format "%[pixel:u.p{0,0}]" info:
srgb(231,214,198)
To check, lets make a swatch:
convert -size 100x100 xc:"srgb(231,214,198)" swatch.png
Or we can recolor the original image:
convert image.jpg -fill "srgb(231,214,198)" -colorize 100 newimage.png
I want to convert image in less pixelate with ImageMagic and I give a try with
convert -resize 20x20 -flop -gaussian-blur 1x5 -scale 100% -scale 500% -colorspace gray -quantize sRGB +dither /png.png /sam_pic.png
And its looking like the following image:
But I want to Increase pixel size that is Image with less pixel
Please suggest me how to do it and modify command.
I got the solution.
Only change the size and increase the scale
convert -resize 18x18 -flop -gaussian-blur 1x5 -scale 110% -scale 500% -colorspace gray /png.png /sam_pic.png
As part of a project I am working on, I need to simply analyze a picture using a CLI Linux application and determining if its dark image (high contrast, low brightness).
So far, I figured out I can use ImageMagick to get verbose information of the image, but not sure how to use that data...or is there a simpler solution?
You could scale the image to a very small one -- one that has a dimension of 1x1 pixels and represents the "average color" of your original image:
convert original.jpeg -resize 1x1 1pixel-original.jpeg
Then investigate that single pixel's color, first
convert 1pixel-original.jpeg 1pixel-jpeg.txt
then
cat 1pixel-jpeg.txt
# ImageMagick pixel enumeration: 1,1,255,srgb
0,0: (130,113,108) #82716C srgb(130,113,108)
You can also get the same result in one go:
convert original.jpeg -resize 1x1 txt:-
# ImageMagick pixel enumeration: 1,1,255,srgb
0,0: (130,113,108) #82716C srgb(130,113,108)
This way you get the values for your "avarage pixel" in the original color space of your input image, which you can evaluate for its 'brightness' (however you define that).
You could convert your image to grayscale and then resize. This way you'll get the gray value as a measure of 'brightness':
convert original.jpeg -colorspace gray -resize 1x1 txt:-
# ImageMagick pixel enumeration: 1,1,255,gray
0,0: (117,117,117) #757575 gray(117,117,117)
You can also convert your image to HSB space (hue, saturation, brightness) and do the same thing:
convert original.jpeg -colorspace hsb -resize 1x1 txt:-
# ImageMagick pixel enumeration: 1,1,255,hsb
0,0: ( 61, 62,134) #3D3E86 hsb(24.1138%,24.1764%,52.4941%)
The 'brightness' values you see here (either of 134, #86 or 52.4941%) is probably what you want to know.