Sign in to follow this  
Red ochre

Codelab cs0012 problem with default code

Recommended Posts

As a new member, firstly, thank you for Paint.net and Codelab. I have no C# experience but have still managed to write some plugins that I am very pleased with.

The problem I have is with the default code for copying the source to the destination without using the loops.

When I use the 'new' option and select the option to include this, it adds the code, but the errors window shows two cs0012 errors.

This also happens if I write the code manually copying from tutorial4. (dst.CopySurface(src,rect.Location,rect;).

The error says: "System.Windows.Int32Rect must add reference to WindowsBase,Version=3.0.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35 (cs0012)"

and the same reference with "System.Windows.Point".

I have tried copying and pasting the code into visual express, but I really am a novice and can't see a way of adding the relevant reference.

I really do not yet understand visual express.

Is this a known issue, or is it my set up? Can it be resolved or do I just have to use the loops to copy everything over before rendering anything new?

Presumably there should be some sort of 'using' statement in the 'hidden' code which points to the relevant library, but since I don't know where this is or the correct syntax to add it - I'm stuck.

Any advice will be appreciated.

Share this post


Link to post
Share on other sites

The code in Tutorial4 on BoltBait's website concerns writing text. As rendering text does not write to every pixel in the destination canvas, you need to precopy the source canvas to the destination canvas to make sure that the destination is completely filled with pixels.

You're probably unlikely to need to precopy the source => destination if you're processing every pixel in your effect. So in Codelab, just use the loops (almost every Codelab source listed here will use them). The idea is that you to 'pick up' each pixel from the source canvas, process it using your effect, and plop it onto the destination canvas.

Feel free to post your code for some in-depth discussion.

Share this post


Link to post
Share on other sites

The code in Tutorial4 on BoltBait's website concerns writing text. As rendering text does not write to every pixel in the destination canvas, you need to precopy the source canvas to the destination canvas to make sure that the destination is completely filled with pixels.

You're probably unlikely to need to precopy the source => destination if you're processing every pixel in your effect. So in Codelab, just use the loops (almost every Codelab source listed here will use them). The idea is that you to 'pick up' each pixel from the source canvas, process it using your effect, and plop it onto the destination canvas.

Feel free to post your code for some in-depth discussion.

Thanks for the reply. - I just wanted to play with generating lines without refence to the src at this stage. Later I would like to pick out say dark pixels( B+G+R<= Amount1) then use this to create the co-ordinates for the g.Drawline command. - Very ambitious, but what's to loose.

Do you know if this(the cs0012 thing) is known issue with Codelab, or is it just me?

I will post some (ametuerish) beta plugins shortly, just got to reread the rules and zip them up.

Thanks again

Share this post


Link to post
Share on other sites

Thought it time to show you how messy my code is - but it seems to run ok for me and it's the first stuff I've written since the Commodore 64. dlls zipped and attached hopefully.

#region UICode

byte Amount1 = 1; // effect|seperate colour phase shift|luminosity phase shift
double Amount2 = 0.0; // [0.0,1.0] phase shift

#endregion

private byte Clamp2Byte (int iValue)
{if (iValue<0) return 0;
if (iValue>255) return 255;
return (byte) iValue;}

void Render(Surface dst, Surface src, Rectangle rect)
{


ColorBgra CurrentPixel;
int B,G,R,A;
double f = Amount2;


for (int y = rect.Top; y < rect.Bottom; y++)
for (int x = rect.Left; x < rect.Right; x++)
{

{CurrentPixel = src[x,y];
B = CurrentPixel.B;
G = CurrentPixel.G;
R = CurrentPixel.R;
A = CurrentPixel.A;



switch((int)Amount1){

case 0:	//seperate colour phase shift


double rad = Math.PI*2;
double phaseB = ((double) 3.0/(double) 3.0*f)*rad;
double phaseG = ((double) 1.0/(double) 3.0*f)*rad;
double phaseR = ((double) 2.0/(double) 3.0*f)*rad;

double b = (double)B/255;double bangle = b*rad;B = 128+(int)(128*Math.Sin((bangle+(rad*f))));
double g = (double)G/255;double gangle = g*rad;G = 128+(int)(128*Math.Sin((gangle+(rad*2*f))));
double r = (double)R/255;double rangle = r*rad;R = 128+(int)(128*Math.Sin((rangle+(rad*4*f))));
break;

case 1:	// luminosity phase shift
double lum = (double)B+(double)G+(double)R;
double rat = (double) lum/ (double)765;

rad = Math.PI*2;
phaseB = ((double) 3.0/(double) 3.0)*rad*(f+1);B = 128 + (int)(rat*(128*Math.Sin((rat*rad)+(phaseB*rad))));
phaseG = ((double) 2.0/(double) 3.0)*rad*(f+1);G = 128 + (int)(rat*(128*Math.Sin((rat*rad)+(phaseG*rad))));
phaseR = ((double) 1.0/(double) 3.0)*rad*(f+1);R = 128 + (int)(rat*(128*Math.Sin((rat*rad)+(phaseR*rad))));

break;
}
// re assemble
CurrentPixel = ColorBgra.FromBgra(Clamp2Byte(,Clamp2Byte(G),Clamp2Byte(R),Clamp2Byte(A));
dst[x,y] = CurrentPixel;
}
}
}

#region UICode
int Amount1=5;	//[0,100]blur radius
int Amount2=220; //[0,255]Flake white threshold
int Amount3=190; //[0,255]Naples yellow threshold
int Amount4=160; //[0,255]Yellow ochre threshold
int Amount5=130; //[0,255]Raw Sienna threshold
int Amount6=100; //[0,255]English red ochre threshold
int Amount7=70; //[0,255]Burnt Umber threshold
int Amount8=40; //[0,255]Raw Umber threshold







#endregion

private byte Clamp2Byte(int iValue)
{
if (iValue<0) return 0;
if (iValue>255) return 255;
return (byte)iValue;
}


void Render(Surface dst, Surface src, Rectangle rect)
{
// Call the Gaussian Blur effect
GaussianBlurEffect blurEffect = new GaussianBlurEffect();
PropertyCollection bProps = blurEffect.CreatePropertyCollection();
PropertyBasedEffectConfigToken bParameters = new PropertyBasedEffectConfigToken(bProps);
bParameters.SetPropertyValue(GaussianBlurEffect.PropertyNames.Radius, Amount1);
blurEffect.SetRenderInfo(bParameters, new RenderArgs(dst), new RenderArgs(src));
blurEffect.Render(new Rectangle[1] {rect},0,1);






ColorBgra CurrentPixel; 
int R, G, B, A;

for(int y = rect.Top; y < rect.Bottom; y++) 
{ 
for (int x = rect.Left; x < rect.Right; x++) 
{ 
CurrentPixel = dst[x,y];
B = (int)CurrentPixel.B;
G = (int)CurrentPixel.G;
R = (int)CurrentPixel.R;
A = (int)CurrentPixel.A;
int mylum = (R + G + B)/3;

// Flake white
if (mylum >= Amount2)
{
B = 210;
G = 250;
R = 250;
}
// Naples yellow
if (mylum >= Amount3 && mylum < Amount2)
{
B = 130;
G = 220;
R = 240;
}

// Yellow ochre
if (mylum >= Amount4 && mylum < Amount3)
{
B = 40;
G = 180;
R = 240;
}
// Raw Sienna
if (mylum >= Amount5 && mylum < Amount4)
{
B = 30;
G = 125;
R = 190;
}
// English red ochre
if(mylum>=Amount6 && mylum<Amount5)
{
B = 25;
G = 80;
R = 200;
}
// Burnt Umber
if(mylum>=Amount7 && mylum<Amount6)
{
B = 10;
G = 40;
R = 130;
}
// Raw Umber
if(mylum>=Amount8 && mylum<Amount7)
{
B = 10;
G = 40;
R = 70;
}
// Lamp black
if(mylum<Amount8)
{
B = 10;
G = 20;
R = 20;
}

// Reassemble the color from R, G, and B
CurrentPixel = ColorBgra.FromBgra(Clamp2Byte(,Clamp2Byte(G),Clamp2Byte(R),Clamp2Byte(A));
dst[x,y] = CurrentPixel; 
} 
} 
}



#region UICode
ColorBgra Amount1 = ColorBgra.FromBgr(220,220,200); // colour to detect
int Amount2 = 15; // [0,765] detection tolerance
ColorBgra Amount3 = ColorBgra.FromBgr(170,170,190); // replacement colour
byte Amount4 =5; //blend type|none|blend1|old blend|dompix|fun|minus 1 add 2
int Amount5 = 150; // [0,765] blend tolerance
int Amount6 = 255; // [0,255] replacement transparency

#endregion

private byte Clamp2Byte(int iValue)
{
if (iValue<0) return 0;
if (iValue>255) return 255;
return (byte)iValue;
}
void Render(Surface dst, Surface src, Rectangle rect)
{
ColorBgra CurrentPixel;
int B, G, R,A,lum, 	B1,G1,R1,A1,lum1,	B2,G2,R2,A2,lum2,	t1,t2,t3, 	dB2,dG2,dR2,dA2,	
obt,ogt,ort,oat,	tb,tg,tr,ta,	f1,f2,f3 ;
int nbt,ngt,nrt,nat, Q,C;

for(int y = rect.Top; y < rect.Bottom; y++) 
{ for (int x = rect.Left; x < rect.Right; x++) 
{ CurrentPixel = src[x,y];

C=Amount4;

B = (int)CurrentPixel.B;	// source pixel
G = (int)CurrentPixel.G;
R = (int)CurrentPixel.R;
A = (int)CurrentPixel.A;
lum=B+G+R;



B1 = (int)Amount1.B;	// colour to detect
G1 = (int)Amount1.G;
R1 = (int)Amount1.R;
A1 = (int)Amount1.A;
lum1=B1+G1+R1;

t1 = (int)Amount2;	//detection tolerance
t2 = (int)Amount5;	//blend tolerance
t3 = t1+t2;
f1 = t1/3;
f2 = t2/3;
f3 = t3/3;

B2 = (int)Amount3.B;	// replacement colour
G2 = (int)Amount3.G;
R2 = (int)Amount3.R;
A2 = (int)Amount6;
lum2=B2+G2+R2;




dB2 = B2-B;
dG2 = G2-G;
dR2 = R2-R;
dA2 = A2-A;

obt=B*(dB2);ogt=G*(dG2);ort=R*(dR2);oat=A*(dA2);	// this blends but not right
tb=(255-dB2)*B2;tg=(255-dG2)*G2;tr=(255-dR2)*R2;ta=(255-dA2)*A2;
nbt=(obt+tb)/255;ngt=(ogt+tg)/255;nrt=(ort+tr)/255;nat=(oat+ta)/255;


if(lum>lum1-t1&&lum<=lum1+t1){B=B2;G=G2;R=R2;A=A2;}// replace with new colour

switch((int)Amount4)
{case 0: //no blend
break;

case 1: //new blend with full transparency
if(lum>=lum1+t1&&lum<lum1+t3){Q=lum-(lum1+t1);//upper blend band
B=((B*Q*255)+(B2*(t2-Q)*255))/(t2*255);
G=((G*Q*255)+(G2*(t2-Q)*255))/(t2*255);
R=((R*Q*255)+(R2*(t2-Q)*255))/(t2*255);
A=((A*Q*255)+(A2*(t2-Q)*255))/(t2*255);}

if(lum>lum1-t3&&lum<=lum1-t1){Q=lum-(lum1-t3); 	//lower blend band
B=((B*(t2-Q)*255)+(B2*Q*255))/(t2*255);
G=((G*(t2-Q)*255)+(G2*Q*255))/(t2*255);
R=((R*(t2-Q)*255)+(R2*Q*255))/(t2*255);
A=((A*(t2-Q)*255)+(A2*Q*255))/(t2*255);} 	

break;
case 2: //original blend


if(lum>=lum1+t1&&lum<lum1+t3){B=nbt;G=ngt;R=nrt;A=nat;}	//upper blend band

if(lum>lum1-t3&&lum<=lum1-t1){B=nbt;G=ngt;R=nrt;A=nat;}	//lower blend band


break;


case 3: //predominant pixel won't blend upper band because colour 2 is too high - have reversed preferencein highband
if(lum>=lum1+t1&&lum<lum1+t3){if(B2<[img=http://forums.getpaint.net/public/style_emoticons/default/boltbait.cool.png]{B=B2;}if(R2<R){R=R2;}if(G2<G){G=G2;}if(A2<A){A=A2;}}	//upper blend band
if(lum>lum1-t3&&lum<=lum1-t1){if(B2<[img=http://forums.getpaint.net/public/style_emoticons/default/boltbait.cool.png]{B=B2;}if(R2<R){R=R2;}if(G2<G){G=G2;}if(A2<A){A=A2;}}	//lower blend band
break;



case 4: // fun
if(B>B1+f1&&B<=B1+f3){B=B2;} 	//upper band
if(G>G1+f1&&G<=G1+f3){G=G2;}
if(R>R1+f1&&R<=R1+f3){R=R2;}
if((B>B1+f1&&B<=B1+f3)||(G>G1+f1&&G<=G1+f3)||(R>R1+f1&&R<=R1+f3)){A=A2;}

if(B<=(B1-f1)&&B>(B1-f3)){B=B2;} 	//lower band
if(G<=(G1-f1)&&G>(G1-f3)){G=G2;}
if(R<=(R1-f1)&&B>(R1-f3)){R=R2;}
if((B<=(B1-f1)&&B>(B1-f3))||(G<=(G1-f1)&&G>(G1-f3))||((R<=(R1-f1)&&B>(R1-f3)))){A=A2;}




break;
case 5: 	//subtract colour 1 and add colour 2
if(lum>=lum1+t1&&lum<lum1+t3){B=(B+B2)-B1; G=(G+G2)-G2; R=(R+R2)-R1; A=(A+A2)-A1;}	//upper blend band

if(lum>lum1-t3&&lum<=lum1-t1){B=(B+B2)-B1; G=(G+G2)-G1; R=(R+R2)-R1; A=(A+A2)+A1;} //lower blend band


break;
}









// Reassemble the color from B, G, and R

CurrentPixel = ColorBgra.FromBgra(Clamp2Byte([img=http://forums.getpaint.net/public/style_emoticons/default/boltbait.cool.png],Clamp2Byte(G),Clamp2Byte®,Clamp2Byte(A));
dst[x,y] = CurrentPixel;


} 
} 

}

Share this post


Link to post
Share on other sites

Fixed the missing code tag boltbait.wink.png

For a Newbie to C# you've done a pretty good job with these!

Each of your files use a call to clamp2byte which I seem to remember is a routine BoltBait used when Rick refactored some of the internal bits of Paint.Net.

You can remove the clamp2byte function and instead call Int32Util.ClampToByte()

You might also want to use indentation to improve readability. In practical terms indent the contents of each set of {} by one tab.

If you use Codelab's UI designer you'll get a few more fields added to your code. Fields such as Author, Submenu and such are available as well as adding your own icon (*.png) to the dll.

I'll have a look at these tonight and come up with a few more suggestions.

Share this post


Link to post
Share on other sites

Thanks - I will improve the readability next time, before I send them - they've sort of evolved rather than being logically designed, bits added as I've found out what things do.

Thanks for corecting the / code mistake, sorry again - will try out the Int32Util.. option.

I will be back tommorow - I've got plenty of questions - if you have the patience

Share this post


Link to post
Share on other sites

Here's a quick update of the first code sample:


/* =================================================== */
/* 	*/
/* Color Contour.cs 	*/
/* (c) 2010 Red Ochre 	*/
/* 	*/
/* Description: Simplifies an image by depresssing the color contours 	*/
/* 	*/
/* ========================================== ======== */

// Name: Color Contour
// Author: Red Ochre
// Submenu: Color
// URL: http://www.getpaint.net/redirect/plugins.html
// Title: Color Contour - 2010 Red Ochre

#region UICode
byte Amount1 = 1; // effect|seperate colour phase shift|luminosity phase shift
double Amount2 = 0.5; // [0.0,1.0] phase shift
#endregion

void Render(Surface dst, Surface src, Rectangle rect)
{
ColorBgra CurrentPixel;
int B,G,R,A;
double f = Amount2;
double rad = Math.PI*2;

for (int y = rect.Top; y < rect.Bottom; y++)
{
	for (int x = rect.Left; x < rect.Right; x++)
	{
		CurrentPixel = src[x,y];
		B = CurrentPixel.B;
		G = CurrentPixel.G;
		R = CurrentPixel.R;
		A = CurrentPixel.A; 	

		switch(Amount1)
	{
		case 0:	//seperate colour phase shift 	 	
		double phaseB = ( 3.0 / 3.0 * f ) * rad;
		double phaseG = ( 1.0 / 3.0 * f ) * rad;
		double phaseR = ( 2.0 / 3.0 * f ) * rad;

		double b = B / 255.0;
	double bangle = b * rad;
	B = 128 + (int)(128 * Math.Sin((bangle+(rad*f))));
		double g = G / 255.0;
	double gangle = g * rad;
	G = 128 + (int)(128 * Math.Sin((gangle+(rad*2*f))));
		double r = R / 255.0;
	double rangle = r * rad;
	R = 128 + (int)(128 * Math.Sin((rangle+(rad*4*f))));
		break;

		case 1:	// luminosity phase shift
		double lum = B + G + R;
		double rat = lum / 765.0;

		phaseB = rad * ( f + 1 );
	B = 128 + (int)( rat *(128*Math.Sin((rat*rad)+(phaseB*rad))));
		phaseG = ( 2.0 / 3.0 ) * rad * ( f + 1 );
	G = 128 + (int)(rat*(128*Math.Sin((rat*rad)+(phaseG*rad))));
		phaseR = ( 1.0 / 3.0 ) * rad * ( f + 1 );
	R = 128 + (int)(rat*(128*Math.Sin((rat*rad)+(phaseR*rad))));
	break;
		}
		// re assemble
		CurrentPixel = ColorBgra.FromBgra( Int32Util.ClampToByte(, Int32Util.ClampToByte(G), Int32Util.ClampToByte(R), Int32Util.ClampToByte(A));
		dst[x,y] = CurrentPixel;
	}
}
}

I'll admit I'm not the most correct C# programmer around this forum (not by a long shot :D). I'm sure others will have improvement for speed, readability and logic!

What I've done is reformatted your original code to improve readability (tabs, indentation & whitespace as required). Yes the formatting on the forum screws with the layout a little bit, but you'll get the idea.

I've also included the header information I spoke of above ( Plugin Name, Author, Submenu, URL & Window Title).

Without altering the effect I've....,

1. Started the default for the Amount2 slider in the middle of the given range.

2. Removed double rad = Math.PI*2; to outside the render loop (no need to repeat this specification for each pixel you process)

3. Replaced the clamp2byte function with Int32Util.ClampToByte().

4. Removed a few unnecessary casts (int) and (double) and cleaned up the math.

With this as a starting point, I'm sure you can improve the other effects to at least the same standard. Give it a go :)

BTW: This is a very nice effect you've created!

Share this post


Link to post
Share on other sites

Thanks for all that work - it is clearer. One thing though - that's actually the code for 'Phsycocolour2' -my fault for uploading them in the wrong order and not adding the the title at the top.

I intend to add more strange effects to this one, as I can just add a new 'case, break' for each block.

The dlls are correctly named but I will rewrite the code to make it tidier and more readable, and possibly organise UI more logically too.

One question - the colour wheel always seems to default to the primary colour setting despite giving it a value in the UI code. Is that just the way it is or can it be made to take the initial value I've assigned ?

Thanks again for the work - I've got loads to learn/discover - I tend to litter the code with casts when I'm 'debugging', then find the fault is somewhere else and forget to go back and write things as simply as possible - lazy habits already!

Share this post


Link to post
Share on other sites

Thanks for all that work - it is clearer. One thing though - that's actually the code for 'Phsycocolour2' -my fault for uploading them in the wrong order and not adding the the title at the top.

I intend to add more strange effects to this one, as I can just add a new 'case, break' for each block.

The dlls are correctly named but I will rewrite the code to make it tidier and more readable, and possibly organise UI more logically too.

One question - the colour wheel always seems to default to the primary colour setting despite giving it a value in the UI code. Is that just the way it is or can it be made to take the initial value I've assigned ?

Thanks again for the work - I've got loads to learn/discover - I tend to litter the code with casts when I'm 'debugging', then find the fault is somewhere else and forget to go back and write things as simply as possible - lazy habits already!

Actually the color wheel seems to be behaving ok now

Share this post


Link to post
Share on other sites

.... One thing though - that's actually the code for 'Phsycocolour2' -my fault....

A great case for adding the comment block at the top of the file. I think it helps to be able to find the filename and brief description of the plugin written here.

... lazy habits already!

Don't get into them (habits)! Better to have Codelab tell you there is a cast missing than have many unnecessary ones littering your code.

Looking forward to the results!

Share this post


Link to post
Share on other sites

I'm working on the next version now, but probably won't post it tonight. Thanks for reviewing the last one - all useful points. The next one should be tidier.

Share this post


Link to post
Share on other sites

Hello again, I've reworked the effects formerly known as "Earths", which is now "Earths and greys", and "psychocolour"is also attached. Hopefully the code is a lot more readable now ?

I haven't started on "contour" yet - as I want to fully rewrite it.

Is this the best forum to 'publish' them, or should I have started a new thread?

Thanks for the help.

/* =================================================== */
/* 	*/
/* Color EarthsnGreys.cs 	*/
/* (c) 2011 Red Ochre 	*/
/* 	*/
/* Description: simplifies tones with choice of palettes 	*/
/* 	*/
/* ========================================== ======== */

// Name: EarthsnGreys
// Author: Red Ochre
// Submenu: Color
// URL: http://www.getpaint.net/redirect/plugins.html
// Title: Earths and Greys - 2011 Red Ochre


#region UICode
int Amount1 = 5;	//[0,100]blur radius
int Amount2 = 220; //[0,255]threshold 1 (whitest above)
int Amount3 = 190; //[0,255]threshold 2
int Amount4 = 160; //[0,255]threshold 3
int Amount5 = 130; //[0,255]threshold 4 (midtone)
int Amount6 = 100; //[0,255]threshold 5
int Amount7 = 70; //[0,255]threshold 6
int Amount8 = 40; //[0,255]threshold 7 (blackest below)
byte Amount9 = 7; // colour palette|earth colours|close tone greys|full range greys|warm to cool neutrals|YORMBCG toned rainbow|YORMBCG straight rainbow|YORMBCG flat toned rainbow|reverse clashing rainbow
#endregion

void Render(Surface dst, Surface src, Rectangle rect)
{
// Call the Gaussian Blur effect
GaussianBlurEffect blurEffect = new GaussianBlurEffect();
PropertyCollection bProps = blurEffect.CreatePropertyCollection();
PropertyBasedEffectConfigToken bParameters = new PropertyBasedEffectConfigToken(bProps);
bParameters.SetPropertyValue(GaussianBlurEffect.PropertyNames.Radius, Amount1);
blurEffect.SetRenderInfo(bParameters, new RenderArgs(dst), new RenderArgs(src));
blurEffect.Render(new Rectangle[1] {rect},0,1);

ColorBgra CurrentPixel; 
int B, G, R, A;
int B1,B2,B3,B4,B5,B6,B7,B8,G1,G2,G3,G4,G5,G6,G7,G8,R1,R2,R3,R4,R5,R6,R7,R8;
B1 = 186;B2 = 130;B3 = 40; B4 = 30; B5 = 25; B6 = 10; B7 = 10;B8 = 10;	// had to put some values here or unassigned variable problem
G1 = 255;G2 = 220;G3 = 180;G4 = 125;G5 = 80; G6 = 40; G7 = 40;G8 = 20;
R1 = 246;R2 = 240;R3 = 240;R4 = 190;R5 = 200;R6 = 130;R7 = 70;R8 = 20;


for(int y = rect.Top; y < rect.Bottom; y++) 
{ 
	for (int x = rect.Left; x < rect.Right; x++) 
	{ 
	switch (Amount9)
	{
	case 0:	// earth colours
	B1 = 186;B2 = 130;B3 = 48; B4 = 30; B5 = 25; B6 = 10; B7 = 10;B8 = 10;
	G1 = 255;G2 = 220;G3 = 173;G4 = 125;G5 = 80; G6 = 40; G7 = 40;G8 = 20;
	R1 = 246;R2 = 240;R3 = 201;R4 = 190;R5 = 200;R6 = 130;R7 = 70;R8 = 20;
	break;

	case 1:	// close tone greys
	B1 = 224;B2 = 196;B3 = 168;B4 = 140;B5 = 112;B6 = 84;B7 = 56;B8 = 28;
	G1 = 224;G2 = 196;G3 = 168;G4 = 140;G5 = 112;G6 = 84;G7 = 56;G8 = 28;
	R1 = 224;R2 = 196;R3 = 168;R4 = 140;R5 = 112;R6 = 84;R7 = 56;R8 = 28;
	break;

	case 2:	// full range greys
	B1 = 255;B2 = 219;B3 = 182;B4 = 146;B5 = 109;B6 = 73;B7 = 37;B8 = 0;
	G1 = 255;G2 = 219;G3 = 182;G4 = 146;G5 = 109;G6 = 73;G7 = 37;G8 = 0;
	R1 = 255;R2 = 219;R3 = 182;R4 = 146;R5 = 109;R6 = 73;R7 = 37;R8 = 0;
	break;

	case 3:	// warm to cool neutrals
	B1 = 193;B2 = 173;B3 = 154;B4 = 134;B5 = 115;B6 = 95;B7 = 75;B8 = 56;
	G1 = 224;G2 = 196;G3 = 168;G4 = 140;G5 = 112;G6 = 84;G7 = 56;G8 = 28;
	R1 = 255;R2 = 219;R3 = 182;R4 = 146;R5 = 109;R6 = 73;R7 = 37;R8 = 0;
	break;

	case 4:	// toned rainbow	
	// White	Yellow Orange Red 	Magenta Blue	Cyan	Green
	B1 = 255;B2 = 146;B3 = 97;B4 = 91;B5 = 165;B6 = 220;B7 = 55;B8 = 0;
	G1 = 255;G2 = 255;G3 = 195;G4 = 92;G5 = 0;G6 = 0;G7 = 56;G8 = 16;
	R1 = 255;R2 = 255;R3 = 255;R4 = 255;R5 = 164;R6 = 0;R7 = 0;R8 = 0;
	//sum = 765, 	656, 	547, 	438, 	329, 	220,	111, 	16 	
	break;

	case 5: 	// straight rainbow 
	// White	Yellow Orange Red 	Magenta Blue 	Cyan 	Green	
	B1 = 255;B2 = 0;B3 = 0;B4 = 0;B5 = 255;B6 = 255;B7 = 255;B8 = 0;	//	note: orange is not 
	G1 = 255;G2 = 255;G3 = 128;G4 = 0;G5 = 0;G6 = 0;G7 = 255;G8 = 255;	//	a perfect division of
	R1 = 255;R2 = 255;R3 = 255;R4 = 255;R5 = 255;R6 = 0;R7 = 0;R8 = 0;	//	the spectrum
	//sum = 765, 	510, 	383, 	255, 	510, 	255, 	510, 	255 
	break;

	case 6: 	// flat toned rainbow 
	// Grey 	Yellow Orange Red 	Magenta Blue 	Cyan 	Green	
	B1 = 170;B2 = 0;B3 = 85;B4 = 128;B5 = 255;B6 = 255;B7 = 255;B8 = 128;	
	G1 = 170;G2 = 255;G3 = 170;G4 = 127;G5 = 0; G6 = 128;G7 = 255;G8 = 255; 
	R1 = 170;R2 = 255;R3 = 255;R4 = 255;R5 = 255;R6 = 127;R7 = 0;R8 = 127;	
	//sum = 510, 	510, 	510, 	510, 	510, 	510, 	510, 	510 
	break;

	case 7: 	// reverse clashing rainbow 
	// White	Magenta Blue 	Cyan 	Green	Yellow Orange Red
	B1 = 255;B2 = 255;B3 = 255;B4 = 255;B5 = 182;B6 = 72;B7 = 100;B8 = 128;
	G1 = 255;G2 = 217;G3 = 218;G4 = 255;G5 = 255;G6 = 255;G7 = 191;G8 = 128;
	R1 = 255;R2 = 255;R3 = 218;R4 = 144;R5 = 181;R6 = 255;R7 = 255;R8 = 255;
	//sum = 765, 	727, 	691, 	654, 	618, 	582, 	546, 	510 	
	break;

	}

	CurrentPixel = dst[x,y];
	B = (int)CurrentPixel.B;
	G = (int)CurrentPixel.G;
	R = (int)CurrentPixel.R;
	A = (int)CurrentPixel.A;
	int mylum = (R + G +  / 3;

	// band 1 - white
	if (mylum >= Amount2) 	{B = B1; G = G1; R = R1;}
	// band 2
	if (mylum >= Amount3 && mylum < Amount2){B = B2; G = G2; R = R2;}
	// band 3
	if (mylum >= Amount4 && mylum < Amount3){B = B3; G = G3; R = R3;}
	// band 4
	if (mylum >= Amount5 && mylum < Amount4){B = B4; G = G4; R = R4;}
	// band 5
	if (mylum >= Amount6 && mylum < Amount5){B = B5; G = G5; R = R5;}
	// band 6
	if (mylum >= Amount7 && mylum < Amount6){B = B6; G = G6; R = R6;}
	// band 7
	if (mylum >= Amount8 && mylum < Amount7){B = B7; G = G7; R = R7;}
	// band 8
	if (mylum < Amount8) 	{B = B8; G = G8; R = R8;}

	// re assemble
	CurrentPixel = ColorBgra.FromBgra( Int32Util.ClampToByte(, Int32Util.ClampToByte(G), Int32Util.ClampToByte(R), Int32Util.ClampToByte(A));
	dst[x,y] = CurrentPixel;



	} 
} 
}





/* =================================================== */
/* 	*/
/* Color Psycocolour.cs 	*/
/* (c) 2011 Red Ochre 	*/
/* 	*/
/* Description: various psychedelic colour effects 	*/
/* 	*/
/* ========================================== ======== */

// Name: Psycocolour
// Author: Red Ochre
// Submenu: Color
// URL: http://www.getpaint.net/redirect/plugins.html
// Title: Psychocolour - 2011 Red Ochre

#region UICode
byte Amount1 = 5; // effect|colour phase shift|tone phase shift|alter by others|seperate colours by others|strange pointillism|out of phase shift
double Amount2 = 0.5; // [0.0,1.0] phase shift
#endregion

void Render(Surface dst, Surface src, Rectangle rect)
{
ColorBgra CurrentPixel;
int B,G,R,A;
double f = Amount2;
double rad = Math.PI*2;
	double phaseB,phaseG,phaseR;



for (int y = rect.Top; y < rect.Bottom; y++)
{
	for (int x = rect.Left; x < rect.Right; x++)
	{
		CurrentPixel = src[x,y];
		B = CurrentPixel.B;
		G = CurrentPixel.G;
		R = CurrentPixel.R;
		A = CurrentPixel.A;
	double lum = B + G + R;
	double rat = lum / 765.0;
 	double b = B / 255.0; double bangle = b * rad;
	double g = G / 255.0; double gangle = g * rad;
	double r = R / 255.0; double rangle = r * rad;


	switch(Amount1)
	{
		case 0:	// colour phase shift 	
			B = 128 + (int)(128 * Math.Sin((bangle + (rad * 1 * f))));
	G = 128 + (int)(128 * Math.Sin((gangle + (rad * 2 * f))));	
	R = 128 + (int)(128 * Math.Sin((rangle + (rad * 3 * f)))); 
			break;

		case 1:	// tone phase shift

	phaseB = (1.0 / 3.0) * rad * f;
	phaseG = (2.0 / 3.0) * rad * f;
	phaseR = (3.0 / 3.0) * rad * f;

	B = 128 + (int)(128 * Math.Sin((rat + phaseB) * rad));
	G = 128 + (int)(128 * Math.Sin((rat + phaseG) * rad));
	R = 128 + (int)(128 * Math.Sin((rat + phaseR) * rad));
	 	break;

	case 2:	// alter each colour by the sum of the other 2
	phaseB = ((B + (255 * f)) / (G + R + 1)) * rad;	// add 1 to denominator incase G + R = 0
	phaseG = ((G + (255 * f)) / (R + B + 1)) * rad;
	phaseR = ((R + (255 * f)) / (B + G + 1)) * rad;

	B = 128 - (int)(128 * Math.Sin(phaseB));
	G = 128 - (int)(128 * Math.Sin(phaseG));
	R = 128 - (int)(128 * Math.Sin(phaseR));
	break;

	case 3:	// seperate colours by others
	b = (G + R) / 510.0; bangle = b * rad;
	g = (R +  / 510.0; gangle = g * rad;
	r = (B + G) / 510.0; rangle = r * rad;

	B = B + (int)(B * Math.Cos((bangle + (rad * 1 * f))));
	G = G + (int)(G * Math.Cos((gangle + (rad * 1 * f))));	
	R = R + (int)(R * Math.Cos((rangle + (rad * 1 * f))));
	break;

	case 4:	// strange pointillism
	double ave = lum / 3;
	double Bdif = ave - B; bangle = f * Bdif;
	double Gdif = ave - G; gangle = f * Gdif;
	double Rdif = ave - R; rangle = f * Rdif;

	B = (int)(B + (ave * Math.Sin(bangle)));
	G = (int)(G + (ave * Math.Sin(gangle)));
	R = (int)(R + (ave * Math.Sin(rangle)));
	break;

	case 5:	// out of phase shift

	phaseB = rad * b / (f + 0.01);	// avoid divide by zero
	phaseG = rad * g / (f + 0.01);
	phaseR = rad * r / (f + 0.01);

	B = B + (int)(B * (Math.Cos(phaseB) - Math.Sin(phaseB)));
	G = G + (int)(G * (Math.Cos(phaseG) - Math.Sin(phaseG)));
	R = R + (int)(R * (Math.Cos(phaseR) - Math.Sin(phaseR)));
	break;

		}
		// re assemble
		CurrentPixel = ColorBgra.FromBgra( Int32Util.ClampToByte(, Int32Util.ClampToByte(G), Int32Util.ClampToByte(R), Int32Util.ClampToByte(A));
		dst[x,y] = CurrentPixel;
	}
}
}

Share this post


Link to post
Share on other sites
Is this the best forum to 'publish' them, or should I have started a new thread?

Yes this is the place to publish 'betas'. I'd create a new thread for each (maybe a day or two apart so you can apply anything learned to the next release).

Share this post


Link to post
Share on other sites

FYI - I liked the Color Phase Shift effect and decided to try it in a Filter Factory format.

(See null54's PdnFF in the Plugins - Publishing Only section)

Works fine!!

Save the following as "Psychocolor0.txt" and Load into null54's PdnFF:

Category: Color
Title: Psychocolor - Color PhaseShift
Copyright: Freeware
Author: Red ochre / [dpl port]

R: put(r*D/255,0),128 + 127*sin(get(0)+ctl(0)*4)/D
G: put(g*D/255,0),128 + 127*sin(get(0)+ctl(0)*8)/D
B: put(b*D/255,0),128 + 127*sin(get(0)+ctl(0)*12)/D
A: a

ctl[0]: Phase Shift

val[0]: 128

These kinds of calculation algorithms work nicely in Filter Factory format.

edit1: updated to latest Red ochre equations.

pleabo

Edited by pleabo

Share this post


Link to post
Share on other sites

    how can I get the psychocolor plugin back? I lost it when I downloaded the newest version of paint.net and I loved this effect I used it a lot and miss it !! it has no equal in my eyes!!please help thanks much,desertwise

Share this post


Link to post
Share on other sites

Hello desertwise,
I'm glad you are finding Psychocolour useful.

Psychocolour  is included in my plugin pack. Click the link in my 'sig' and it should take you to the plugin pack download page.

Also, EER has created a plugin index which is really useful for finding the right download page for plugins.

http://forums.getpaint.net/index.php?/topic/15260-plugin-index/  ;)

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this