rearrange vertical pixel row

Questions and postings pertaining to the usage of ImageMagick regardless of the interface. This includes the command-line utilities, as well as the C and C++ APIs. Usage questions are like "How do I use ImageMagick to create drop shadows?".
peterthebest
Posts: 6
Joined: 2015-07-14T15:34:19-07:00
Authentication code: 1151

rearrange vertical pixel row

Post by peterthebest »

hello,
i want to rearrange the vertical/ horizontal pixel rows in jpg / tiff pictures -
so that every row gets a new position.
it takes couple of hours depending on the size.
is there a way to do it with imagemagick?
regards
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: rearrange vertical pixel row

Post by snibgo »

What rules determine the new positions?

How large are the images (how many rows and columns)? How many images? Is the rearrangement the same for all images? What are the images? Not ordinary photographs, I suppose.

This could be done at the command line: crop the image into one image per row. Re-arrange the images with "-insert" etc. Then append them together.

Another method would be a custom program (or process module) that created the rows in one image from the rows of another image.

Note: Doing this with JPEG compression is probably a bad idea, as it is lossy.
snibgo's IM pages: im.snibgo.com
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: rearrange vertical pixel row

Post by fmw42 »

Is this a random shuffling (of every row or column or just one single row or column) or do you have a specific order that you need? Are you going to shuffle both the rows and columns in the same image? If so, which should be done first?

Please also aways provide your IM version and platform
peterthebest
Posts: 6
Joined: 2015-07-14T15:34:19-07:00
Authentication code: 1151

Re: rearrange vertical pixel row

Post by peterthebest »

thanks for responding.

for example i got an image height 4000 x width 6000 px which shows a house with garden.
now i want the vertical pixel rows to be rearranged randomly so that each row gets a new place within
the 4000 x 6000 px and a new row next to it.

right now i do it manually in photoshop by setting the selection to height 4000 px width 1px copy paste....
it takes very long.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: rearrange vertical pixel row

Post by fmw42 »

I think you will need to write a script that loops over each image. For each image, it crops every column as user snibgo said above and stores the resulting images in a folder (-crop 1x4000 see http://www.imagemagick.org/Usage/crop/#crop_equal). Then with the OS rename the files with a common name and random id between 0 and 6000 (but which does not duplicate any id). Use leading zeros such as image-0001.jpg to image-6000.jpg. Then simply append all the columns in renamed order

Code: Select all

convert *.jpg +append result
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: rearrange vertical pixel row

Post by fmw42 »

In unix, you can create a list of filenames that are randomly shuffled from a sequential list of numbers. No duplicates and none skipped.

Code: Select all

for ((i=0; i<20; i++)); do
echo $i
done |\
awk 'BEGIN{srand() }
{ lines[++d]=$0 }
END{
    while (1){
    if (e==d) {break}
        RANDOM = int(1 + rand() * d)
        if ( RANDOM in lines  ){
	   		printf "image-%d.jpg\n",lines[RANDOM]
            delete lines[RANDOM]
            ++e
        }
    }
}'

image-7.jpg
image-18.jpg
image-3.jpg
image-17.jpg
image-11.jpg
image-9.jpg
image-1.jpg
image-12.jpg
image-2.jpg
image-5.jpg
image-10.jpg
image-0.jpg
image-15.jpg
image-13.jpg
image-8.jpg
image-4.jpg
image-19.jpg
image-16.jpg
image-6.jpg
image-14.jpg

You can then write that to a file instead and use

convert @file +append result

once you have cropped the image into all its columns and stored them in a folder.

You can crop the individual columns and store them into one layered miff file and then use the following to access the randomized layers of the miff file

Code: Select all

for ((i=0; i<20; i++)); do
echo $i
done |\
awk 'BEGIN{srand() }
{ lines[++d]=$0 }
END{
    while (1){
    if (e==d) {break}
        RANDOM = int(1 + rand() * d)
        if ( RANDOM in lines  ){
	   		printf "image[%d].miff\n",lines[RANDOM]
            delete lines[RANDOM]
            ++e
        }
    }
}'

image[7].miff
image[14].miff
image[18].miff
image[16].miff
image[9].miff
image[10].miff
image[0].miff
image[17].miff
image[5].miff
image[11].miff
image[8].miff
image[1].miff
image[2].miff
image[13].miff
image[12].miff
image[15].miff
image[6].miff
image[3].miff
image[19].miff
image[4].miff


Change 20 to 6000 for your case in either method. And change the code to redirect to a new file.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: rearrange vertical pixel row

Post by fmw42 »

P.S. Can you explain why you need to do this kind of processing? What is the goal or purpose? If you just need an image with random values, you can use +noise random (or gaussian, etc). See http://www.imagemagick.org/Usage/canvas/#random and http://www.imagemagick.org/script/comma ... .php#noise
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: rearrange vertical pixel row

Post by snibgo »

An alternative method would be to crop to single rows (or columns), then "-swap" each image in the list with a random image, then append them together. As this wouldn't write the rows to files, it should be quicker. It would still need a script to build the list of swaps.

Can it be done in a single command? Almost. We can make an absolute displacement map, where each row of the map is a random value. However, this will probably result in some input rows each copied to more than one output row, and some input rows not copied at all.

For example, using the built-in "rose:" which is 70x46 pixels, Windows BAT syntax:

Code: Select all

convert ^
  ( -size 46x70 gradient: -rotate 90 ) ^
  ( -size 1x46 xc: ^
    +noise Random ^
    -channel R -separate +channel ^
    -scale "70x46^!" ^
  ) ^
  ( -size 70x46 xc: ) ^
  -combine ^
  rose: ^
  +swap ^
  -compose Distort ^
    -set option:compose:args 35x23 ^
    -composite ^
  rose_rand.png
Image
snibgo's IM pages: im.snibgo.com
peterthebest
Posts: 6
Joined: 2015-07-14T15:34:19-07:00
Authentication code: 1151

Re: rearrange vertical pixel row

Post by peterthebest »

@ fmw42 i need that for an art project. just want the new generated picture to conatain pixels from the picture - no added noise.
@ snibgo looks good. i think you nailed what i want. could you give me a "short" step by step instruction what to do?
i have never done anything with imagemagick. would be great

thanks guys
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: rearrange vertical pixel row

Post by fmw42 »

I do not think you have answered my earlier question. What version of IM and what platform are you using? Syntax is different for windows and unix.
peterthebest
Posts: 6
Joined: 2015-07-14T15:34:19-07:00
Authentication code: 1151

Re: rearrange vertical pixel row

Post by peterthebest »

oh sorry
my main os is mac yosemite but i also have an 2011 win 7 laptop.
i've never used imagemagick.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: rearrange vertical pixel row

Post by fmw42 »

Snibgo's script above is for Windows. If you want to convert to unix syntax, see http://www.imagemagick.org/Usage/windows/ and reverse the changes mentioned. In unix, 1) parens must be escaped as \( and \) 2) end of lines and other escapes are \ not ^ and 3) any %% are just % in unix.
peterthebest
Posts: 6
Joined: 2015-07-14T15:34:19-07:00
Authentication code: 1151

Re: rearrange vertical pixel row

Post by peterthebest »

hello,
i tried it on mac but it doesn't work. my test image is called uno.jpg and its 800x800 px.


convert \
  \( -size 800x800 gradient: -rotate 90 \) \
  \( -size 1x800 xc: \
    +noise Random \
    -channel R -separate +channel \
    -scale „800x800\!“ \
  \) \
  \( -size 800x800 xc: \) \
  -combine \
  uno: \
  +swap \
  -compose Distort \
    -set option:compose:args 35x23 \
    -composite \
  uno.jpg

i get the following error:

convert: unable to open image ` ': No such file or directory @ error/blob.c/OpenBlob/2675.
convert: no decode delegate for this image format `' @ error/constitute.c/ReadImage/501.
convert: unable to open image ` ': No such file or directory @ error/blob.c/OpenBlob/2675.
convert: no decode delegate for this image format `' @ error/constitute.c/ReadImage/501.
convert: unable to open image ` ': No such file or directory @ error/blob.c/OpenBlob/2675.
convert: no decode delegate for this image format `' @ error/constitute.c/ReadImage/501.
convert: unable to open image ` ': No such file or directory @ error/blob.c/OpenBlob/2675.
convert: no decode delegate for this image format `' @ error/constitute.c/ReadImage/501.
convert: unable to open image ` ': No such file or directory @ error/blob.c/OpenBlob/2675.
convert: no decode delegate for this image format `' @ error/constitute.c/ReadImage/501.
convert: unable to open image ` ': No such file or directory @ error/blob.c/OpenBlob/2675.
convert: no decode delegate for this image format `' @ error/constitute.c/ReadImage/501.
convert: unable to open image ` ': No such file or directory @ error/blob.c/OpenBlob/2675.
convert: no decode delegate for this image format `' @ error/constitute.c/ReadImage/501.
convert: unable to open image ` ': No such file or directory @ error/blob.c/OpenBlob/2675.
convert: no decode delegate for this image format `' @ error/constitute.c/ReadImage/501.
convert: invalid argument for option `-scale': „800x800!“ @ error/convert.c/ConvertImageCommand/2619.

what does " -set option:compose:args 35x23 \ " mean - why 35x23 ?


im sorry but i am not into terminal / command line .....
thanks guys
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: rearrange vertical pixel row

Post by snibgo »

peterthebest wrote: uno: \
This line is garbage. There is no file-format or built-in image called "uno:". Perhaps you meant to put "uno.jpg".

"35x23" is the half-dimensions of the input I used. Instead, you could use "100%x100%".

EDIT:
peterthebest wrote:convert: invalid argument for option `-scale': „800x800!“
Don't use a word-processor that uses smart-quotes.
snibgo's IM pages: im.snibgo.com
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: rearrange vertical pixel row

Post by anthony »

WARNING: snobgo's solution will produce a image with randomly selected rows from the original image.

UNIX/Mac version... (for referance)

Code: Select all

convert \
  \( -size 46x70 gradient: -rotate 90 \) \
  \( -size 1x46 xc: +noise Random -channel R -separate +channel \
    -scale "70x46!" \
  \) \
  \( -size 70x46 xc: \) \
  -combine \
  \
  rose: +swap \
  -compose Distort -set option:compose:args 35x23 -composite \
  rose_rand.png
As it is purely random selection, it is very possible (actually extremely likely) that some rows will be lost, and others duplicated.

The solution to this loss/duplication is to generate that gradient and then use -spread to randomly swap pixels in the gradient. Something like

Code: Select all

convert \
  \( -size 1x70 gradient: -rotate -90 \) \
  \( -size 1x46 gradient: -spread 46 \
     -channel R -separate +channel \) \
  \( -size 1x1 xc: \) \
  -scale 70x46\! -combine \
  \
  rose: +swap \
  -compose Distort -set option:compose:args 35x23 -composite \
  rose_rand.png
Unfortunately -spread seems to include virtual pixels in its selection of pixels to swap, which in turn means we still get some data loss. In this case it would be better if spread would only pick real image pixels for the swaps. Actually that is what I would have expected it to do, and not involve virtual pixels at all.

Because of this we are sill needing something (external script) to generate a randomly 'shuffled' gradient to achieve the requested goal. So Fred's solution while more complex is still the more correct solution.

Also remember distortions (or relative displacements) can generate interpolated pixel data (pixel color mixing). So some careful verification of results is also needed. I don't remember a lot from the time I implemented the Distort composition, as I had a lot in the pipeline back then.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
Post Reply