ropensci / magick

Magic, madness, heaven, sin
https://docs.ropensci.org/magick
Other
459 stars 64 forks source link

Could we please, add `image2` as optional argument to `image_fx()` #250

Closed dmi3kno closed 4 years ago

dmi3kno commented 4 years ago

As recently raised in #244, image_fx() currently works only with single image. In some cases, second image may have to be provided to enable fx operation comparing/copying data between images. Could we please, add image2 as a last, optional argument? that is

image_fx(image, expression = "p", channel = NULL, image2=NULL)

Originally posted by @dmi3kno in https://github.com/ropensci/magick/issues/138#issuecomment-627590648

jeroen commented 4 years ago

Hmm the fx() method in C++ doesn't have a second parameter, see docs.

Perhaps this is something we need to do in a separate al to image-composite?

@dlemstra how would one use fx()in c++ with multiple images?

dmi3kno commented 4 years ago

Just to make sure we're on the same page, I am talking about this usecase

If your IM is too old to understand the "-clut" operator or you want to do something out of the ordinary, such as a 2 dimensional color lookup table, then you can roll your own using the General DIY Operator, FX. For example here is a slow, but equivalent command to the above.

convert gray_image.jpg  gradient_ice-sea.png -fx 'v.p{0,u*v.h}'  gray_recolored_fx.jpg
dlemstra commented 4 years ago

@jeroen The fx operation only works on a single image.

dmi3kno commented 4 years ago

Ok. If that's the case, I guess the issue can be closed, but I still do not understand what u and v in the fx command correspond to then. Documentation says:

Source Images

The symbols u and v refer to the first and second images, respectively, in the current image sequence. Refer to a particular image in a sequence by appending its index to any image reference (usually u), with a zero index for the beginning of the sequence.

dlemstra commented 4 years ago

I misunderstood what you were trying to accomplish. Thought you wanted to perform the same operation on multiple images at the same time. You could call fxImages from STL.h instead on a list of images to perform this operation @jeroen. But be aware of this:

It is important to note the special role played by the first image. This is the only image in the image sequence that is modified, other images are used only for their data.

It might be a good idea to allow specifying a list as the second arguments instead of just image2 when calling image_fx.

jeroen commented 4 years ago

Thanks Dirk! Actually I wasn't aware of fxImages because it's not in the STL docs. I should have checked the STL header files.

How exactly should I use this STL method? For example if we have a vector of images and I run:

for_each ( vec->begin(), vec->end(), Magick::fxImage(std::string("some expression")));

Does this then only modify the first image in the vector? Because most STL methods modify each image in the vector?

jeroen commented 4 years ago

@dmi3kno I have added a function image_fx_sequence that allows you to pass formulas that treat the input as a sequence with multiple images. Does that work for you?

dlemstra commented 4 years ago

This method is an exception @jeroen. The list is linked together and apparently you are even allowed to not have the image that will be modified in the list because you will need to pass that as an argument.

dmi3kno commented 4 years ago

Yes, @jeroen this seems to be working. The #244 can be closed as well, i think because there's now a solution for colorlookup

library(magick)

gimg <- image_read("gray_image.jpg") %>% 
  image_convert(type="TrueColor")
gimg

gray_image

gr <- c(
  image_blank(10, 33, pseudo_image = "gradient:wheat-brown"),
  image_blank(10,33, pseudo_image = "gradient:Brown-LawnGreen"),
  image_blank(10,34, pseudo_image = "gradient:DodgerBlue-Navy")
  ) %>% image_append(stack=TRUE) 

gradient3

image_fx_sequence(c(gimg, gr), 'v.p{0,u*v.h}') 

combined