![]() |
| |||||||
| Software Photoshop, Paintshop Pro, Painter, etc., and all their various plugins. Of course, you can also discuss all other programs, as well. |
| | Thread Tools |
|
#1
| ||||
| ||||
| FilterMeister - General Information (byRo: this thread was split from another much longer one - so some posts may seem out of context) FilterMeister (FM) is a plug-in for Adobe Photoshop®-compatible graphics programs with the ability to create professional plug-in filters which can be distributed on a royalty-free basis. It’s available here http://www.filtermeister.com There are loads of samples and documentation at the site and there is a User group here. http://groups.yahoo.com/group/FMML/ we can share filters and ideas and perhaps learn the C+ style language. Ken Last edited by byRo; 05-06-2006 at 12:17 PM. Reason: byRo: Thread split |
|
#2
| ||||
| ||||
| A question... How many folks aroud here already have experience with FilterMeister? I started messing around in Filter Factory, but the interface was sooo ugly that I lost interest. Now I'm getting fired up again. Rô |
|
#3
| ||||
| ||||
| Quote:
Something I picked up. is that the Border code done this way is very inefficient. You will be testing every single pixel in the image, to just alter a few of them which happen to be the border area. Much quicker, in terms of execution time, would be to set up some loops to change only the borders. (Although, admittedly, in this case, it probably isn't really worth it). Talking of execution speed... I've been tearing apart the "Recursive Gaussian Blur" code. I noticed that the author does not use X and Y, but instead uses x_start, x_end, y_start and y_end. I, thinking how clever I was , substituted the X and Y into the code - which then ran 6 times slower.Stroker? Help! What's going on? Rô |
|
#4
| ||||
| ||||
| When you have an image in FM, the dimensions are 0 to X and 0 to Y. Actually, I think it's X-1 and Y-1. Now, the preview can only show so much. The viewable part of the image in the preview is x_start to x_end and y_start to y_end. When you use these, you are only processing only what is in the preview instead of the entire image. The suck part is when using isTilable=False. This is going to be the case when using recursive Gauss. When previewing with rG, just the preview is processed and all is fine. However, once you click Okay, the entire image is now one big tile instead of little chunks. Add buffer usage and memory can sky rocket. This means that rG will bog down with bigger images when you click Okay, but should be fine while previewing. Make sense? edit: Just found out my 8 year old is being taught French in school (public). Her reading level is very advanced, so she is in a special class. Just had to share that. Last edited by Stroker; 02-17-2006 at 01:05 PM. |
|
#5
| ||||
| ||||
| Quote:
Quote:
(I hated French whan I was at school, but that's probably because I HAD to take it - now I speak Portuguese all day!) Rô |
|
#6
| ||||
| ||||
| OK, stroker, here's some to start.... 1) The "OnCtl" handler gets activated whenever something happens in a control (or in the dialog?). The "ForEveryTile" also gets activated. If I set a control to "no event" (or something like that) can I avoid the "ForEveryTile"; 2) It seems that every time the ForEveryTile starts, the image buffers (pget / tget / t2get) get cleared. Right? 3) Inside the "OnFilterStart" handler, I don't have access to x_start etc. (OK, that's pretty obvious) but can I still access the source pixels (src(x,y,z))? 4) If I want to do an initial one-off transformed image (like in my equalization plugin) and don't want to keep on recalculating the same thing needlessly, I imagine (based on question 2 and 3) that I could calculate the "transform" in the "OnFilterStart" handler and then would have to store in an array (memory). Right? 5) Seems that the scope of variables is only within the handler. If I want to pass a value between handlers (or iterations) the options would be: a) A control on the dialog;6) Seems that I remember you sneaked in something like "extendedui", what's that? 7) Where's your secret supply of FM info? OK, you don't have to reply to 7) if it really is a secret, OK? Rô |
|
#7
| ||||
| ||||
| 1. I'm not sure. I'll look into this. 2. See #1, but I'm fairly sure buffers are cleared. 3. You should have access to those variables. Try this: Code: %ffp
OnFilterStart:{
Info("%d %d",x_start,x_end);
return false;
}
4. This one is kind of tricky. Currently it has to be hacked using a system global variable. Code: %ff
OnFilterStart:{
if (i9==0){
i9=123456;
// more code here to run once
}
return false;
}
OnCtl(n):{
if ((n==CTL_CANCEL || n==CTL_OK) && e==FME_CLICKED) i9=0; //RESET IT
return false;
}
A truly run once structure is in the works. I think it is called OnFilterInit. Personally, I'm partial to OnFilterAlpha. 5. A common method is to use a control and hide it. I'm pretty sure get() and put() are global. Arrays ala allocArray() are global. There are some named variables that are global, like i9 k0 str0, but I don't know too much about these. 6. "extendedui" is for drop-down lists. Combobox, I believe. I can't remember what it does off the top of my head, but I know I like it so I just use it automatically. Should be in UserGuide.pdf. 7. The docs (HTML and PDF), FMML archive, source codes, and lots of time reading. I also keep a notebook - a honker 3' D-ring by my right elbow. I've been at it for close to a year and I'm only just starting to feel the groove. Roland, you should check out the FM Mailing List (FMML). Lots of good FM users there including the developers. Sounds like you might be getting too big for my breaches and you will need their help more than mine soon enough. Kudos. Last edited by Stroker; 03-01-2006 at 05:12 PM. |
|
#8
| ||||
| ||||
| Thanks, Stroker, really appreciate the help. I've just done a couple of hours wandering around FMML, what a pity it isn't all neat and organized like RetouchPRO. I'll be setting up some test codes for the points still in doubt. Get back to you later. Rô |
|
#9
| ||||
| ||||
| Question 7. Google “FilterMeister Code”. Apart from FilterMeisters own Web page you get straight back here. Thanks to Stroker this thread IS THE best supply of FM info. Ken. |
|
#10
| ||||
| ||||
| Quote:
Code: %ffp
ctl(0): CHECKBOX , "Initialize" , pos=(285,50), size=(40,12), Val = 1
ctl(1): PUSHBUTTON, "GO" , pos=(285,70), size=(40,12)
ForEveryTile:{
if (ctl(0)) { //Initialize the filter
i0 = 199; // init i0
put( 199, 0); // init i(0)
allocArray(0,1,0,0,1);
putArray(0,0,0,0,199); // init array()
setCtlVal(0,0); // end of initialize routine
}
//Normal tile processing
Info( "Values \ni0 is %i \nget(0) is %i \narray is %i", i0, get(0), getArray(0,0,0,0));
i0++; //increment i0
put(get(0)+1,0); //increment i(0)
putArray(0,0,0,0,getArray(0,0,0,0)+1); //increment array()
return true;
}
So, yes, i0 (up to i9) and arrays are global, the "put/get array" is not. Quote:
Last edited by byRo; 03-02-2006 at 06:33 PM. |
|
#11
| ||||
| ||||
| is it just me or do none of the examples in the tutorials compile? I managed to get the blur example to compile by changing 'true' to return true... but some of them are like for(y=0; y and then they go onto the next line so I cant fill in the blanks because I dont know what they should be |
|
#12
| ||||
| ||||
| Hi Nancy. It’s nice to see you here. I have never had a problem compiling any of the examples I have tried (I have not tried them all) The ‘Border Code’ (Post 8) is straight from the manual. I have tried most of the example source code which is downloaded with FilterMeister, and again, never had a problem. One problem I have had occasionally is in the formatting of the code. Try this. Instead of copying and pasting straight to FM. First paste the code to Notepad. Then copy the code from Notepad and Paste this to FM. If that does not help then can you give a specific example of code that is not compiling. Ken |
|
#13
| ||||
| ||||
| This is straight out the manual - for blend and labelled example Code: %ffp
//This example blends the image with a mirrored version of itself
ctl(0): "Ratio",range=(0,255),val=128
ctl(1): combobox(vscroll),action=preview, color=#FFFFFF,fontcolor=#0000ff, size=(50,200),
text="Normal\nDissolve\nThreshold\nThreshold 2\nMultiply\nScreen\nOverlay\nSoft Light\nHard Light\nDodge\nBurn\nDarken\nLighten\nExclusion\nDifference\nNegDif 1\nNegDif 2\nSubtract\nAdd\nExpose",
val=0
ForEveryTile:
{
for (y=y_start; y
updateProgress(y,y_end);
for (x=x_start; x
for (z=0; z
pset(x, y, z, blend (src(x,y,z), src(X-x,Y-y,z) , z, ctl(1),ctl(0)) );
}}}
return true;
}
This example is one from the tutorials Code: %ffp
Category: "FM Tutorial"
Title: "Blur II"
Author: "Ilyich the Toad"
ctl[0]:"Blur &Width",range=(2,scaleFactor*X/2),val=3,pagesize=3,linesize=1
ctl[1]:"Blur &Height",range=(2,scaleFactor*Y/2),val=3,pagesize=3,linesize=1
ForEveryTile:
{
int kernelheight; int kernelwidth;
int xlook; int ylook;
int sum; int amount; int progress;
setCtlRange(0,2,scaleFactor*X/2); setCtlRange(1,2,scaleFactor*Y/2);
kernelheight=max(ctl(1)/scaleFactor, 1); //avoiding zero kernel on small preview
kernelwidth=max(ctl(0)/scaleFactor, 1); //avoiding zero kernel on small preview
progress=0;
// --------------------------------
// Blur - first pass (along X-axis)
// --------------------------------
for (y=0; y < Y; y++) {
if(updateProgress(progress,2*Y)) break;
progress++;
for (x=0; x < X; x++) {
for (z= 0; z < Z; z++) {
sum=0; amount=0;
for (xlook=0; xlook<kernelwidth; xlook++)
{
sum+= src((x+xlook-kernelwidth/2),y,z);
amount++;
}; //accumulate pixels in a raw
tset(x,y,z,sum/amount); //divide the sum onto kernel size
}
}
}
// ---------------------------------
// Blur - second pass (along Y-axis)
// ---------------------------------
for (y=0; y < Y; y++) {
if(updateProgress(progress, 2*Y)) break;
progress++;
for (x=0; x < X; x++) {
for (z= 0; z < Z; z++) {
sum=0; amount=0;
for (ylook=0; ylook<kernelheight; ylook++)
{
sum+= tget(x,(y+ylook-kernelheight/2),z);
amount++;
}; //accumulate pixels in a column
pset(x,y,z,sum/amount); //divide the sum onto kernel size
}
}
}
updateProgress(0, 100);
true;
}
|
|
#14
| ||||
| ||||
| Hi, Nancy, good to see you around here. Working with Filtermeister is a bit like trying to get into Deep Paint - very little organized information at all. You just have to keep reading around and trying to piece the stuff together. Stroker and I, can probably help out with most things if you need. This is the first one corrected: Code: %ffp
//This example blends the image with a mirrored version of itself
ctl(0): "Ratio",range=(0,255),val=128
ctl(1): combobox(vscroll),action=preview, color=#FFFFFF,fontcolor=#0000ff, size=(50,200),
text="Normal\nDissolve\nThreshold\nThreshold 2\nMultiply\nScreen\nOverlay\nSoft Light\nHard Light\nDodge\nBurn\nDarken\nLighten\nExclusion\nDifference\nNegDif 1\nNegDif 2\nSubtract\nAdd\nExpose",
val=0
ForEveryTile:
{
for (y=y_start; y<y_end; y++) {
updateProgress(y,y_end);
for (x=x_start; x<x_end; x++) {
for (z=0; z<Z; z++) {
pset(x, y, z, blend (src(x,y,z), src(X-x,Y-y,z) , z, ctl(1),ctl(0)) );
}}}
return true;
}
Anything else you need, your wish is my command. Rô |
|
#15
| ||||
| ||||
| Craig (Kraellin) requested a masking filter here http://www.retouchpro.com/forums/software/12957-free-equalization-plugins-byro.html I can’t find any way to make this selection in one go. The magic wand will select the painting quite easily using a setting of 10 and making several ‘Adds’ Using colour range or Hue/sat will not work. Any Ideas? Ken. Code: Ctl(0): "Red Min", Pos=(280,10),val=255,track Ctl(1): "Red Max", Pos=(280,20),val=255,track Ctl(2): "Green Min", Pos=(280,30),val=255,track Ctl(3): "Green Max", Pos=(280,40),val=255,track Ctl(4): "Blue Min", Pos=(280,50),val=255,track Ctl(5): "Blue Max", Pos=(280,60),val=255,track R: ctl(1) > ctl(0) & r > ctl(0) & r < ctl(1)? A=255 :r G: ctl(3) > ctl(2) & g > ctl(2) & g < ctl(3)? A=255 :g B: ctl(5) > ctl(4) & b > ctl(4) & b < ctl(5)? A=255 :b |
|
#16
| ||||
| ||||
| 'y_end', ofcourse, why didnt I think of that Something I noticed running the lab desat code Stroker posted was that it introduced a lot of compression artifacts - I assume thats because of the ForEveryTile rather than ForEveryPixel, I tried altering the code but then it became so slow. I've noticed that with other code examples, it takes quite a while to do and recreates the preview everytime you move a slider or press a button etc. |
|
#17
| ||||
| ||||
| Ok, I think I'm getting to grips with what does what... but how do you set the tile size? |
|
#18
| ||||
| ||||
| Quote:
Quote:
JPG compression applies different parameters to Luminosity and Colours - basically using an 8 x 8 pixel base for Luminosity and 16 x 16 for Colours. Also, I believe, JGP will discard a lot more Colour information than Luminosity when you lower the quality. This is done because we perceive the artifacts much less in the colours. Now, if you are going to make use of the (noisy) colour information to make your new Luminosity then the artifacts will be more visible. Quote:
Quote:
hope this helped, Rô |
|
#19
| ||||
| ||||
| Just seems to me that if the tile is the whole image then the function is moot. A lot of the examples I've seen start with ForEveryTile then for(z) for (y) for(x), which is equivalent to ForEveryPixel, surely? Last edited by NancyJ; 03-06-2006 at 10:32 AM. |
|
#20
| ||||
| ||||
| Well, yes, sortta, not quite. Sweeping through the (preview) image is automatic and happens every time you alter anything. As FM is doing this this, it will run parts of your code as identified by "handlers". The name of the handler (good word to remember) tells you when it will be called. OnFilterStart: Just once at the start ForEveryTile: Once for each tile ForEveryPixel: Once for each pixel OnFilterEnd: Just once at the end OnCtl(n): Every time you touch a control. So, if you use ForEveryPixel, then you don't need to (well, "should not", actually) use any looping, 'cuz FM is already doing that for you. (Which is probably what happened to you - for every pixel, you code was looping through the whole tile.) If the tile is the whole image, then OnFilterStart and ForEveryTile are just about the same thing. As posted somewhere above, there is no handler for when your filter is first activated - the OnFilterStart runs once every time you touch something. If you want to initialize (as I did) then you need a flag. As in stroker's suggestion, you can use one of the pre-definied global integers (i0...i9) which are initalized as 0. Just test for 0, and set it to 1 after initializing the filter. OnCtl(n) is used for administration of the dialog. You can test for n to discover which control was actioned. Quote:
Hope that explained it. If you have any more doubts, please ask. Rô Last edited by byRo; 03-06-2006 at 09:57 AM. |
|
#21
| ||||
| ||||
| well, true to my nature, i couldnt stand to wait and read through 100 pages of docs. so, i just jumped in and started editing i dont understand all the rest of that code that came with that ffp, but my little test did take the image from 0 to 255 saturation using the first slider, instead of what was originally there. and it also seemed to move the other range, the 8-15 one, up and down a bit. this was just a simple test and by no means what i'm fully after here, but ok. been a long while since i played with code. i shld also mention that even though this desired filter is meant for grays, i do want to primarily have it work on 8 bit grays, not grayscale. fine if it also works on grayscale, but mostly i convert any true grayscale i'm working on into 8 bit grays anyways before actually working on it. so the filter shld primarily be for 8 bit rgb mode. attached is an image of the pic i worked on and the code i adjusted. the adjusted code is highlighted in red. the rest is what was there in the filter to begin with. craig |
|
#22
| ||||
| ||||
| Quote:
If you are going to use the same filter many times then a .8bf is better, if you're doing a one-off then no need. The license for creating .8bf's is around US$20. Rô |
|
#24
| ||||
| ||||
| Quote:
If your code ain't so fast, it won't be able to keep up with the slider and the preview will be choppy. In this case better without track, then the code will be executed only at the end of the slider movement. Quote:
Quote:
Or...just ask here! I'm sure Stroker and I will have some good answers. Rô |
|
#25
| ||||
| ||||
| Ro, thanks. so, this line: "int r,g,b,Gray, rv,gv,bv;" is the line that defines-declares-initializes the variables? looks like it. so 'rv', 'gv', and 'bv' are just arbitrary variable names the person used in the code and not pre-set or reserved. ok. then why are 'R', 'G' and 'B' not declared in some programs? and the same with 'r', 'g', 'b', 'x', and 'y'? are those reserved? also, in going over stroker's last piece of code posted, the line: Quote:
i'm going to also assume in that code that 'float', up near the top, just under the 'int' line, means: 'make these next items floating point variables'. that right? the docs, or my ability to find things, seems to be woefully lacking here as far as definitions of things and what they do. i do recognize a few things from having studied C briefly a few years back, but technical writing has always been my bane in learning things like this. the writer knows certain given things and seems to always think i know them also. heh...i dont. and that's fine if you're teaching others that have that background of basics already down pat, but again, i dont. i need 'filtermeister for dummies' ah well, i'll keep looking. oh, and i also did find out that 'standard' means simply, 'use the default control, the slider or scrollbar'. craig |
|
#26
| ||||
| ||||
| Quote:
so ok, i'm curious here; why did stroker use floating point values at all in that last piece of code? because of the division done in that one formula? and i'm completely lost as to the purpose of this line: avg=r*0.30 + g*0.59 + b*0.11; he seems to be weighting the r g b values differently, but why? why not just use the //avg=(r+g+b)/3; line which he remmed out? craig Last edited by Kraellin; 04-02-2006 at 09:00 AM. |
|
#27
| ||||
| ||||
| Real quick and I'm off to bed. Integers are number without decimals places or fractional parts. int a=1, b=10, c=257; Floats and doubles can have decimals places. float pi=3.14159; I used floats in the last code because I needed percentages. You know, numbers between 0 and 1. This is to weight the sliders from 0% to 100%. I'll get into this later. Quote:
|
|
#28
| ||||
| ||||
| stroker, ah, ok. int does equal integer then. wasnt sure if it was integer or initialize or something else. so, just adding 'int' tells the following items that they are now integer type variables. cool. and the same with 'float', only that makes them floating points. ok. and yes, forgot about the percentages. i see that now. thanks seems a bit of an odd way to weight the values, but i'm guessing that has to do with how luminosity is stored in the various channels, so ok. it works, so cant argue much with that. ok, i altered your code to make it 32 bands/ranges. i also upped the percentage values in the ctl(x) lines to (-1000,1000). this allows me to take most values to complete black or complete white rather than just percentages of the original. i mean, they're still percentages, but now they just go further. and yes, i changed the divide by 51 accordingly. with 16 bands i changed it to 16. with 32, i changed it to 8. also, the 'standard' thing was causing the sliders to write over each other with this many sliders, so i changed back to the longhand way. i've still got to figure out how to resize the interface window. it currently doesnt want to hold all my sliders in view when you first compile the code. they are there, but the window has to be opened up more to see them completely. and, i think i saw a piece of code in the docs about a 'reset' button. gonna need that too. setting 32 sliders back to 0, each having a range of -1000 to 1000 is a bit of a task. so, gotta do that too. this is cool stuff. i just posted a pic in the photo art forum i did with this new filter. it's in the 'red flower' section/post. i mean, why limit your creativity to just using other folk's plugins and programs.... make your own! very cool. craig |
|
#29
| ||||||
| ||||||
| Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Philosophical aside This Luminosity stuff exists only in our heads. In Nature there is just a mixture of different wavelengths, nothing separated into greyscale / Colour information. Our eyes are, mostly, sensitive to two basic wavelengths corresponding to (what we call) Green and Red. Why? Because, for a very long time, those are the two colours that really mattered as a question of life or death. The Blue information was always more hazy and gets included as a filler. /Philosophical aside Resize the dialog. Inlcude this and you'll have a nice big dialog. Code: OnFilterstart:{
setCtlPos(CTL_OK, 420,280, -1, -1);
setCtlPos(CTL_CANCEL, 460,280, -1, -1);
setCtlPos(CTL_PREVIEW, 5, 5,245,265);
setCtlPos(CTL_ZOOM, 200,285, 50, 10);
setCtlPos(CTL_PROGRESS, 5,285,185, 10);
return false;
}
|
|
#30
| ||||
| ||||
| Quote:
(or if you have any doubts Rô |
| Thread Tools | |
| |
| | ||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Important security info | chrishoggy | Salon | 11 | 02-16-2007 02:31 PM |
| scratch info in info palette | seanarmenta | Photoshop Help | 5 | 08-11-2006 08:32 PM |
| Using info from green channel, any help? | RobArnold | Image Help | 8 | 12-07-2005 06:04 AM |
| File > File Info - Does Elements have this menu command? | DannyRaphael | Photoshop Elements Help | 5 | 07-26-2004 07:18 PM |
| Mend Tool - Patron Info button error. | jimlay | Hidden Power Support | 6 | 02-29-2004 12:49 PM |