"Dirty/Grunge" Canvas

and by dirty I don’t mean it needs to be refreshed… but I mean it looks like it is smudged with dirt/dust
and old used piece of paper for example. or well used playing cards

However I would prefer to NOT use a precomposed static image… I would love to find some “easy” method that will create a random dirt pattern, but still be realistic.

perhaps “grunge” is a better word

How fast does it need to be? How large are the canvases you’ll be manipulating?

doesn’t need to be “real” fast, as I will be creating picture objects at run time… so these won’t need to be rendered in “real time”, they will be cached.

and maximum will probably be 300 x 420

Here’s a quick and dirty approach that I whipped up that just messes with the rgbSurface of a Picture, then paints that to the graphics of the canvas. It only sortof works if your canvas is mostly square, and if you squint real hard looking at it - but hopefully it’ll give you some ideas about what you could do the rgbSurface to produce the look you are after without needing a pre-built bitmap.

not quite what I was looking for , but I get your idea… thanks

Change Kimballs Paint event code in Grundgy Canvas to

[code]Sub Paint(g As Graphics, areas() As REALbasic.Rect) Handles Paint

//paints a “grungy paper” effect on the g, then raises the myPaint event.

dim p as new Picture(g.width, g.height, 32)
dim s as RGBSurface = p.RGBSurface

dim r as new Random

For y As Integer = 0 To p.height - 1

For x As Integer = 0 To p.width - 1

  //do something interesting, based on the xy coords of the pixel.
  dim minRange as integer = 200
  dim maxRange as integer = 255
  
  dim red as integer = r.InRange(minRange, maxRange)
  dim green as integer = r.InRange(minRange, maxRange)
  dim blue as integer = r.InRange(minRange, maxRange)
  
  s.Pixel(x, y) = rgb( red, green, blue )

Next

Next

g.drawPicture(p, 0, 0)

raiseEvent myPaint(g)

End Sub[/code]

You can also play around with the minRange and MaxRange values a bit.

You could further change the finished picture by adding “stains” (like circular impressions, tears, etc)

how to do that??

Simple: add a mask to the picture and use that :wink:

The easy way: goggle for “texture with stains” or “grund texture”.
The hard way: get some paper, splash some water on it. Wait until dry and scan the paper.

I’m even sure I could find quite a few texture images on my harddrive. Yup. Took less than 10 seconds.

[quote=350577:@Beatrix Willius]The easy way: goggle for “texture with stains” or “grund texture”.
The hard way: get some paper, splash some water on it. Wait until dry and scan the paper.

I’m even sure I could find quite a few texture images on my harddrive. Yup. Took less than 10 seconds.[/quote]

But thanks anyways

[code]
dim p as new Picture(g.width, g.height, 32)
dim s as RGBSurface = p.RGBSurface

dim rnd as new Random

For y As Integer = 0 To p.height - 1
For x As Integer = 0 To p.width - 1
//do something interesting, based on the xy coords of the pixel.
dim minRange as integer = 230
dim maxRange as integer = 255

dim red as integer = rnd.InRange( minRange, maxRange )
dim green as integer = rnd.InRange( minRange, maxRange )
dim blue as integer = rnd.InRange( minRange, maxRange )

s.Pixel(x, y) = rgb( red, green, blue )

Next
Next

// add a stain: use a mask m

dim m as new Picture(g.width, g.height, 32)

// fill the mask with a black background = fully drawn

m.Graphics.ForeColor = rgb( 0, 0, 0 ) // &c000000 // black
m.Graphics.FillRect( 0, 0, g.Width, g.Height )

// make drops of different shades of grey on the mask

for i as integer = 1 to 23 // lets do 23 in the lower right corner with random diameter

dim rndPoxitionX as integer = rnd.InRange( 300, g.Width - 10 )
dim rndPoxitionY as integer = rnd.InRange( 200, g.Height - 10 )
dim rdnCircleDiameter as integer = rnd.InRange( 10, 40 )

// draw some circles aka stains with random greyness

dim minRange as integer = 10
dim maxRange as integer = 50

dim greyValue as integer = rnd.InRange( minRange, maxRange )

m.Graphics.ForeColor = rgb( greyValue, greyValue, greyValue ) // some form of darkish grey

// draw grey circles at random position
m.Graphics.FillOval( rndPoxitionX, rndPoxitionY, rdnCircleDiameter, rdnCircleDiameter )

next i

p.ApplyMask( m )

g.drawPicture( p, 0, 0 )

raiseEvent myPaint( g )[/code]

… now if my computer screen wasn’t so dirty I could actually see the stains better …

… and now with coffee cup stain:

[code]
dim p as new Picture(g.width, g.height, 32)
dim s as RGBSurface = p.RGBSurface

dim rnd as new Random

For y As Integer = 0 To p.height - 1
For x As Integer = 0 To p.width - 1
//do something interesting, based on the xy coords of the pixel.
dim minRange as integer = 230
dim maxRange as integer = 255

dim red as integer = rnd.InRange( minRange, maxRange )
dim green as integer = rnd.InRange( minRange, maxRange )
dim blue as integer = rnd.InRange( minRange, maxRange )

s.Pixel(x, y) = rgb( red, green, blue )

Next
Next

// add a stain: use a mask m

dim m as new Picture(g.width, g.height, 32)

// fill the mask with a black background = fully drawn

m.Graphics.ForeColor = rgb( 50, 50, 50 ) // &c000000 // grey, so you can have darker AND lighter spots
m.Graphics.FillRect( 0, 0, g.Width, g.Height )

// Lets draw a bigger darker circle, like a glass stain

dim rndPoxitionX as integer = rnd.InRange( -10, g.Width - 100 )
dim rndPoxitionY as integer = rnd.InRange( -10, g.Height - 100 )

dim rdnCircleDiameter as integer = rnd.InRange( 250, 400 )

// set greyness
dim minRange as integer = 100
dim maxRange as integer = 200
dim greyValue as integer = rnd.InRange( minRange, maxRange )

// draw ONE circle aka stain with random greyness but DARKER and in steps

for i as integer = 1 to 20 // lets do 100 with random diameter

m.Graphics.ForeColor = rgb( greyValue + i, greyValue + i, greyValue + i ) // some form of darkish grey

// draw grey circles at random position
m.Graphics.DrawOval( rndPoxitionX + i, rndPoxitionY + i, rdnCircleDiameter - i - i, rdnCircleDiameter - i - i )

next i

// make drops of different shades of darker grey (= lighter on picture) on the mask

for i as integer = 1 to 4000

rndPoxitionX = rnd.InRange( -10, g.Width - 10 )
rndPoxitionY = rnd.InRange( -10, g.Height - 10 )

rdnCircleDiameter = rnd.InRange( 2, 8 )

// draw some circles aka stains with random greyness but LIGHTER

minRange = 0
maxRange = 40

greyValue = rnd.InRange( minRange, maxRange )

m.Graphics.ForeColor = rgb( greyValue, greyValue, greyValue ) // some form of darkish grey

// draw grey circles at random position
m.Graphics.FillOval( rndPoxitionX, rndPoxitionY, rdnCircleDiameter, rdnCircleDiameter )

next i

p.ApplyMask( m )

if DrawMask then
g.drawPicture( m, 0, 0 )
else
g.drawPicture( p, 0, 0 )
end if

raiseEvent myPaint( g )[/code]