More filter example source, or tutorials please.
Copy link to clipboard
Copied
Are there any nub tutorials for plugin writers that people have found useful? I find it interesting how cluttered full of useless requests this discussion area is.
I have a lot of experience in c++, and in pixelbender now, but trying to decipher the code used in just the dissolve filter, with few other open source examples is making my eyes cross.
Explore related tutorials & articles
Copy link to clipboard
Copied
Photoshop Plug-Ins Part 1 http://www.mactech.com/articles/mactech/Vol.15/15.04/PhotoshopPlug-InsPart1/index.html
Copy link to clipboard
Copied
Yeah I been through that, it's a good general explination but it's also 10+ years old, and doesn't actually really help that much in explaining the breakdown of something like the dissolve filter which is super complex. I need the simplest possible photoshop filter so I can just look at the algorithm dofilter section and understand how the math works. I just want to create some simple filters and I can't even do that because of the complexity I'm seeing.
How about for instance, the diffuse filter without all the scripting recognition coding in it, so that would eliminate that complexity at least, so I can also therefore see by elimination what that is actually composed of.
I found an example of just the absolutely simplist filters on that one guy's site that's also 10+ years old. Ok one of them actually does work still in cc2015. But then the coding is just in c++ and I can't get it to compile in visualc++ 2013 myself.
The biggest problem I'm having is understanding and finding how the variables are passed through the resource/visual portion of the program. The boxes and radio buttons are named numbers? I can't trace them. When I click on them, like I do when I develop my own program it opens the mfc wizard instead of taking to the relevant code like every visual c++ tutorial shows I should be able to do. What's with that? I can't trace the logic at all.
Copy link to clipboard
Copied
What I need is someone to shoot a video of them building a plugin and explain the logic of what they're doing ideally. Absolutely nothing like that exists as far as I know.
Copy link to clipboard
Copied
Would it help me maybe in terms to think in more of c++ world. So I know a lot of plugins these days seem to function as their own programs, but then also have a plugin that interfaces with photoshop. So say I have a program in c++ that loads an image and changes it to be more red. What would I need to make that c++ standalone program a photoshop plugin?
I don't see how all these amazing plugins exist without almost any sort of tutorials at all. How can anyone learn this stuff?
Copy link to clipboard
Copied
Alright how about this. Is a frame a kernel? Like wtf, why would you redefine kernel as anything other than a kernel? Why would you call it a frame? Can you just not access a pixel with a plugin? But the pixelbender plugin is a plugin, so you have to be able to right? So wth.
Copy link to clipboard
Copied
Sorry you are so frustrated with the Dissolve SDK example and the Photoshop API. Hopefully I can help answer some of your questions. The Photoshop API is from 1990 so a 10 year old video is actually pretty new! It is a C interface and many plugins written on windows in 32 bit still run today and run on many different versions of Photoshop. There are some C++ wrappers in the SDK but not many. From your comments it seems you are developing on windows so I will focus on win32 for the UI part.
For filter plug-ins the FilterRecord found in PIFilter.h is what you need to study and make sure you read all the comments on the items in that structure. Inside of the Dissolve example you can look at the gFilterRecord to see which parts of the record are manipulated to get the job done. DoFilter is the main "algorithm." The other SDK examples have this round about #define mechanism and pass around a global to each structure which I thought was odd so I changed it for Dissolve.
There is no concept of a kernel in the Photoshop API examples. Your pixelbender plugin programming probably wont get you far. In theory you could write it kernel based as that is what the pixelbender framework is doing but I wont be talking about kernels. PixelBender is a Photoshop filter plug-in. Too bad we can't give out the source to it.
The code gets complicated because Photoshop is complicated. Image mode, image depth, selection masks, large documents just to name a few. The UI puts up a "proxy" view that is a scaled down view of the document and the code has to deal with that. Ideally, we would have a tutorial that adds in all this complexity but one was never developed.
DissolveRectangle is the function that is walking each pixel on the layer and determining if it should set it to a new color. That is the Dissolve algorithm and you will not find any "face recognition" or other complicated algorithms in the SDK examples. You would have to read some research papers or other sources for that information.
So there are all of my excuses, now let's see if we can answer more of your questions.
The Dissolve example uses a random number generator to determine if that pixel should be changed or not. See UpdateDissolveBuffer and this line:
*dissolve = ((unsigned16) rand()) % 100 < gParams->percent;
Inside of DissolveRectangle there is also checks for the maskPixel (did the user select it) and/or are we ignoring that selection made by the user gParams->ignoreSelection with this logic:
bool leaveItAlone = false; if (maskPixel != NULL && !(*maskPixel) && !gParams->ignoreSelection) leaveItAlone = true; if (*dissolve && !leaveItAlone)
The changing of the layer data for an eight bit image is done with this line: (This is one plane at a time, do all the reds, then blues, then greens. I hope I have that order correct!)
*pixel = color;
Looking at DoFilter you see that we are doing a rectangle (tile) at a time to reduce our memory footprint. Photoshop documents can get very large. Photoshop is tiled and planer internally so operating on that same boundary in a plug-in is ideal. You can see the setup for each tile tile loop and then each plane loop in DoFilter. You could change it to "chunky" and ask for RGB values by manipulating the plane loop and adjusting here. (a lot more of the program would need to be adjusted of course to handle "chunky" image data)
gFilterRecord->outLoPlane = gFilterRecord->inLoPlane = plane;
gFilterRecord->outHiPlane = gFilterRecord->inHiPlane = plane;
The basic idea is you set up the FilterRecord for what you want, via setting rectangles and planes and then call advanceState(). This populates the data buffers in the FilterRecord with our new request.
gParams->percent comes from defaults, or the UI, or the scriptig parameters. The UI gets set via the DissolveProc in DissolveUIWin.cpp during the WM_COMMAND message see this line:
gParams->percent = (short)GetDlgItemInt(hDlg, kDEditText, NULL, TRUE);
To recapp: The source code is your documentation. Understand it clearly by running it in the debugger.
Build your plug-in and install into the Plug-Ins folder. Set a breakpoint at the top of DoFilter. Use Debug->Attach to Process and find the "Photoshop.exe". Select Dissolve filter from the Photoshop menu item.
Copy link to clipboard
Copied
Ah wow! Thanks so much for this, this is the most help I've had in months of on and off trying to understand this. I was pretty much at my wits end.
Ok I was wondering most about debugging, and if attaching it to photoshop would work or not. The filter I tried to call that way crashed photoshop, which wasn't a good thing.
I'm working on trying to understand all the bits of the dissolve filter, and an open source plugin that a guy made called psgamma on github that's based on the dissolve filter, just as a first step. He claims it works and compiled on an earlier vs but doesnt compile in vs2013, it seems to be missing some logic I'm not understanding in what he was trying to do or how to correct it. I got it to compile but it crashes photoshop any time I call it. lol
Ok thanks so much again. I'll go over what you wrote and try to add that in. I think I've made the most progress I've made today of the past few months. I'm also studying visual c++ a lot more cause my knowledge is clearly lacking in that field.
I'm using windows x64. I was able to compile the dissolve filter and get it to work without any problems under 64 bit..so is there really any difference besides what the compiler has to do or something, or in the includes or something?
One of the other filters I've been studying is greyc, which is a noise/paint filter and their unmasksharp2. Both are fascinating to look at, the architecture seems completely different. One thing with them is that they can use the graphics processor. I want to change and update the ui with sliders on it, because the ui is horrible, but again that sort of thing is beyond me, and again I don't understand how the ui portion of visual c++ interacts with the code yet at all. I can't find the call outs to the boxes/preview or anything in the code.
I Have them working in photoshop 64 bit cc2015, with a compile made by them or someone else. I can get it to compile on mine for 64 bit but the one I compile won't show up in the photoshop filter menu for some reason. Either it's not set for 64 bit or it's not updated for cc2015 or something. Not sure what's going on with it. Could that be it though, that something has to be different for it to be read in 64 bit?
Copy link to clipboard
Copied
The cuda developer instructions contains some good bits of simple filters it seems...is cuda no longer supported though? I tried to install the sdk and it failed.
http://developer.download.nvidia.com/compute/cuda/Photoshop/CUDAFilters4.pdf
This is what I need, just dofilter sections that show different simple things, of course this also uses the cuda sdk..if it's no longer working anymore then pretty much everything is useless, but at least i can see what's happening in the exampleses
I got the cuda sdk to install, there are tons of examples to look at, several of which are based on the dissolve filter. This could really be what I've been needing.
So it turns out the photoshop cuda filters are now missing from the sdk, although there are a ton of other examples of gpu programs. I can at least study them a bit I suppose but I guess they'll be difference since they dont contain any photoshop sdk handles..
Copy link to clipboard
Copied
Figured it out a bit! Added a slider! It actually works! Sliders FTW STill not really understanding the math bit, but now that I can futz with sliders I feel a lot more comfortable. lol
Sliders first, then the math. lol
Copy link to clipboard
Copied
Are you still there Tom?
I've been over that article 20 times, and it's just not sinking into me how to actually do anything with the sdk, or how to actually get to the math of working with an image.
Coming from pixel bender I'm used to being able to just read individual pixels. So with the sdk we have to look at frames? How can we actually access the rgb data at all? I just dont understand it. So all the values are in FilterRecord ? But I mean it's just so hopelessly complex. I don't understand how anyone does anything with this mess?
Could you explain to me the basic logic and the required sdk structures/data values behind just say reading the image data and changing the image to be more red? In pixelbender you would just read the image with the samplenearest function, or linear, which gives you and lets you change the coordinates of the sample if you choose to modify it, and the rgba values, which you can then manipulate with math, if I wanted more red I just say + the .r value of whatever I've assigned the sample to, and then output the result, and wala done.
How would that work with a simple photoshop plugin?
Copy link to clipboard
Copied
Been studying up on c a lot the past couple months on and off. feel a bit better equipped to look at this code but still having a hard time understanding the filterrecord, and how it breaks planes into accessable variables. The first 4 planes are the rgba values right...so now trying to access those individually instead of just piling through them with high-low?
I'm trying to add sliders to control the rgb values of the dissolve color instead of radio buttons, having a devil of a time.
I see in one part of the filter rgb values are broken out and I was able to manipulate the colors a bit using that, and trying to place different variables in them, but I can't seem to hook up a slider to those values, and even if I did I know that's not the right way to go about it, the correct way should be to access the planes and modify those in the filter record right?
//-------------------------------------------------------------------------------
//
// InitData
//
// Initialize the gData pointer
//-------------------------------------------------------------------------------
void InitData(void)
{
CopyColor(gData->colorArray[0], gFilterRecord->backColor);
SetColor(gData->colorArray[1], 255, 0, 0, 255);
SetColor(gData->colorArray[2], gParams->red, gParams->green, gParams->blue, gParams->alpha);
SetColor(gData->colorArray[3], gParams->red, gParams->green, gParams->blue, gParams->alpha);
SetColor(gData->colorArray[4], gParams->red, gParams->green, gParams->blue, gParams->alpha);
SetColor(gData->colorArray[5], gParams->red, gParams->green, gParams->blue, gParams->alpha);
I added pointers to declared parameters in this but of course it's not doing anything cause i have no idea what I'm doing. lol
Would it be something more like
red->inLoPlane = red->outLoPlane =0; ?
Would that set the red plane value to a red parameter that I'm controlling with a slider?
?
sigh
I think I need to modify this for loop right?
for (int16 plane = 0; plane < gFilterRecord->planes; plane++)
{
// we want one plane at a time, small memory foot print is good
gFilterRecord->outLoPlane = gFilterRecord->inLoPlane = plane;
gFilterRecord->outHiPlane = gFilterRecord->inHiPlane = plane;
// update the gFilterRecord with our latest request
*gResult = gFilterRecord->advanceState();
if (*gResult != noErr) return;
// muck with the pixels in the outData buffer
uint8 color = 255;
int16 expectedPlanes = CSPlanesFromMode(gFilterRecord->imageMode,
0);
if (plane < expectedPlanes)
color = gData->color[plane];
DissolveRectangle(gFilterRecord->outData,
gFilterRecord->outRowBytes,
gFilterRecord->maskData,
gFilterRecord->maskRowBytes,
GetOutRect(),
color,
gFilterRecord->depth);
}
Also when I try to debug as you suggested it asks me for a photoshop.pdb file...? Do I have to output the debug 8bf file to the plugin directory or something, but that is protected on my system so I can't output to it...?
Found an interesting thread here that has some basic code searching for inloplane on google. This is what I need, it shows more how to interface with the controls a little on a basic level.
Copy link to clipboard
Copied
Alright, so still working on trying to make sliders to change the colors instead of radio buttons for the dissolve filter...for the past couple weeks now, and having dismal results.
I notice the percent function which I've changed now to a slider loops through the scripting.cpp file... What scripting language is it even using? What's going on with that
Oh I realize this is just for the actions, and it says it's for the adobe scripting engine. I'll research that.

