Idea for a new filter/command (not thought out)

There are various filters that allow mask, but some do not, so here’s what I was thinking, a new one called: apply_mask, in the vein of apply_tiles where you give it a filter and mask and it applies the filter masked.
I understand there are tricks that often work, but a separate command would ‘unclutter’ the applying of mask I think, maybe.
And it can’t be too complex to add to the GMIC toolbox right?

Thoughts? Stupid/useless idea? or not?

Addendum: Maybe a better name would be apply_masked.

That’s a good idea indeed. I’ll see what I can do.

Oh cool, I’m glad you like the idea.
I would be pretty pleased if it took off and if people had a benefit from it.

Here is a first attempt for such a command.
I’ve added it to the G’MIC stdlib, but only for 3.6.2_pre for now on.
But you can copy/paste this command code in your user.gmic file to get it:

#@cli apply_mask : "command",[opacity_mask],_max_opacity_mask
#@cli : Apply specified command on selected images but only inside the specified mask.
#@cli : Default value: 'max_opacity_mask=1'.
#@cli : $ image.jpg 100%,100% noise. 10 blur. 2%,0 ge. 50% blur. 0.5% normalize. 0,1 +apply_mask.. "sepia whirls",[-1]
apply_mask : check ${"is_image_arg $2"}" && isnum(${3=1})"
  e[^-1] "Apply command '$1' on image$?, using opacity mask $2 and max opacity mask value $3."
  m "__apply_mask : $1"
  pass$2 if !w rm. return fi
  foreach[^-1] {
    +l { __apply_mask if $! k. fi }
    if $!>1
      if [w,h,d]!=[w#-2,h#-2,d#-2] r. {-2,[w,h,d]},100% fi
      if s!=s#-2 to_colormode 0 fi
      pass. 1 if [w,h,d]!=[{-2,[w,h,d]}] +r. {-2,[w,h,d]},100% rm.. fi
      j[0] ..,0,0,0,0,1,.,$3
      k[0]
    fi
  }
  rm.
  um __apply_mask

Here’s what the help displays, when invoked from the terminal:

And here is the result of the image generated by the given example:

Thanks David, very interesting to play with I find.

I have a question though, can I nest it in an apply_tiles? When I try it fails, I think it might be having twice double quotes in it that is my issue there. I did escape them and each command works on its own but not one inside another.

Short explanation: When I first thought of this was when I was messing around using apply_tiles with 0 overlap and 50% on the x axis to apply filters to stereographic images, for instance a vignette filter that has to be applied separately on each half of the image.
So now I wonder if I can use apply_mask in such a manner, by using it nested in such an instance of apply_tiles. To get apply_mask done on each half of the image separately in one command. Or does that fall outside the scope of what is possible?
I mean obviously I could first split and then rejoin the two halves, I just wonder if nesting is possible.

Oh BTW, is this included in the just released 3.6.2 final? I did not see it in the on the road to 3.7 changes post.

One more question if you permit me:
Just out of curiosity why is the n 0,1 (which I assume is to get it to a required ‘fraction between 0 and 1’) external and not part of the command? Don’t you always need to do that to the mask?

Edit: I just realized that you can use ‘cut’ because the n 0,1 is external.
So you can do n 0,1 cut 0,0.2 for instance, I should have figured there was a good reason.
Addendum: or gcd_softcut or something of course.

It is possible, but honestly that would be not the easiest way.
As G’MIC is able to manage a stack of images, you can easily first split your image in two parts, then apply each filter independently on each part, then recompose your image afterwards.
Like this:

$ gmic input.jpg -split x,2 -vignette 100 -append x -o output.jpg

and if you want to add an apply_mask call between, you won’t have to backslash the double quotes.

No, as you said if you want to apply the filter with a lower mask opacity everywhere, then you don’t want to normalize the mask in [min,max] range.

Thanks for the reply.

And I already saw it’s in 3.6.2-final now, so that’s answered too :slight_smile: