Xojo Conferences
XDCMay2019MiamiUSA

Platforms to show: All Mac Windows Linux Cross-Platform

/Picture/Image effects/imagetransformation
Function:
Required plugins for this example: MBS Picture Plugin
You find this example project in your Plugins Download as a Xojo project file within the examples folder: /Picture/Image effects/imagetransformation
This example is the version from Fri, 17th Nov 2016.
Project "imagetransformation.rbp"
FileTypes
Filetype text
Filetype special/any
End FileTypes
Class Window1 Inherits Window
Control source Inherits Canvas
ControlInstance source Inherits Canvas
EventHandler Sub DropObject(obj As DragItem, action As Integer) dim p as picture dim f as folderItem do if obj.pictureAvailable then p = obj.picture elseif obj.folderItemavailable then f = obj.folderItem p = f.openaspicture end LoadPicture p loop until not obj.NextItem End EventHandler
EventHandler Sub Open() me.acceptpictureDrop me.acceptfileDrop("special/any") End EventHandler
EventHandler Sub Paint(g As Graphics, areas() As REALbasic.Rect) if sourcepicture = nil then g.drawstring "Drag picture here",10,me.height/2 g.drawrect 0,0,me.width,me.height else g.drawpicture sourcepicture,0,0,g.Width,g.Height,0,0,sourcepicture.Width,sourcepicture.Height end End EventHandler
End Control
Control destination Inherits Canvas
ControlInstance destination Inherits Canvas
EventHandler Function MouseDown(X As Integer, Y As Integer) As Boolean Dim d as DragItem if destinationpicture<>nil then d=New DragItem(self, Me.left,Me.top,Me.width,Me.height) d.picture=destinationpicture d.Drag //Allow the drag end End EventHandler
EventHandler Sub Paint(g As Graphics, areas() As REALbasic.Rect) if destinationpicture = nil then g.drawrect 0,0,me.width,me.height else g.drawpicture destinationpicture,0,0,me.width,me.height,0,0,destinationpicture.width,destinationpicture.height end End EventHandler
End Control
Control PushButton1 Inherits PushButton
ControlInstance PushButton1 Inherits PushButton
EventHandler Sub Action() dim m(2,2) as double dim t as integer dim p as PictureMatrix3DMBS // matrix for gray if CheckPlugin.Value then p=new PictureMatrix3DMBS p.Matrix(0,0) = 0.3 p.Matrix(1,0) = 0.59 p.Matrix(2,0) = 0.11 p.Matrix(0,1) = 0.3 p.Matrix(1,1) = 0.59 p.Matrix(2,1) = 0.11 p.Matrix(0,2) = 0.3 p.Matrix(1,2) = 0.59 p.Matrix(2,2) = 0.11 p.SourcePicture=sourcepicture t=Ticks call p.run t=ticks-t destinationpicture=p.DestinationPicture else m(0,0) = 0.3 m(1,0) = 0.59 m(2,0) = 0.11 m(0,1) = 0.3 m(1,1) = 0.59 m(2,1) = 0.11 m(0,2) = 0.3 m(1,2) = 0.59 m(2,2) = 0.11 t=Ticks destinationpicture = sourcepicture.matrix3d(m,checkdither.value) t=Ticks-t end if destination.refresh StaticText6.text=str(t) End EventHandler
End Control
Control StaticText1 Inherits Label
ControlInstance StaticText1 Inherits Label
End Control
Control PushButton2 Inherits PushButton
ControlInstance PushButton2 Inherits PushButton
EventHandler Sub Action() dim m(2,2) as double dim t as integer dim p as PictureMatrix3DMBS // matrix for sepia if CheckPlugin.Value then p=new PictureMatrix3DMBS p.matrix(0,0) = 0.3 * 255/255 p.matrix(1,0) = 0.59 * 255/255 p.matrix(2,0) = 0.11 * 255/255 p.matrix(0,1) = 0.3 * 168/255 p.matrix(1,1) = 0.59 * 168/255 p.matrix(2,1) = 0.11 * 168/255 p.matrix(0,2) = 0.3 * 60/255 p.matrix(1,2) = 0.59 * 60/255 p.matrix(2,2) = 0.11 * 60/255 p.SourcePicture=sourcepicture t=Ticks call p.run t=ticks-t destinationpicture=p.DestinationPicture else m(0,0) = 0.3 * 255/255 m(1,0) = 0.59 * 255/255 m(2,0) = 0.11 * 255/255 m(0,1) = 0.3 * 168/255 m(1,1) = 0.59 * 168/255 m(2,1) = 0.11 * 168/255 m(0,2) = 0.3 * 60/255 m(1,2) = 0.59 * 60/255 m(2,2) = 0.11 * 60/255 t=ticks destinationpicture = sourcepicture.matrix3d(m,checkdither.value) t=Ticks-t end if StaticText7.text=str(t) destination.refresh End EventHandler
End Control
Control PushButton3 Inherits PushButton
ControlInstance PushButton3 Inherits PushButton
EventHandler Sub Action() dim m(3,3) as double dim t as integer dim p as PictureMatrix3DMBS // matrix for video component YCbCr if CheckPlugin.Value then p=new PictureMatrix3DMBS p.matrix(0,0) = 0.5 p.matrix(1,0) = -0.42 p.matrix(2,0) = -0.08 p.matrix(0,1) = 0.3 p.matrix(1,1) = 0.59 p.matrix(2,1) = 0.11 p.matrix(0,2) = -0.17 p.matrix(1,2) = -0.33 p.matrix(2,2) = 0.5 p.matrix(0,3) = 0 p.matrix(1,3) = 128 p.matrix(2,3) = 128 p.SourcePicture=sourcepicture t=Ticks call p.run t=ticks-t destinationpicture=p.DestinationPicture else m(0,0) = 0.5 m(1,0) = -0.42 m(2,0) = -0.08 m(0,1) = 0.3 m(1,1) = 0.59 m(2,1) = 0.11 m(0,2) = -0.17 m(1,2) = -0.33 m(2,2) = 0.5 m(0,3) = 0 m(1,3) = 128 m(2,3) = 128 t=ticks destinationpicture = sourcepicture.matrix3dwithconstants(m,checkdither.value) t=Ticks-t end if StaticText8.text=str(t) destination.refresh End EventHandler
End Control
Control StaticText2 Inherits Label
ControlInstance StaticText2 Inherits Label
End Control
Control PushButton4 Inherits PushButton
ControlInstance PushButton4 Inherits PushButton
EventHandler Sub Action() dim h(2),v(2) as double dim t as integer dim p as PictureConvolutionMBS if CheckPlugin.Value then p=new PictureConvolutionMBS p.hor(0) = 0.25 p.hor(1) = 0.5 p.hor(2) = 0.25 p.ver(0) = 0.25 p.ver(1) = 0.5 p.ver(2) = 0.25 p.ValueCount=3 p.SourcePicture=sourcepicture t=ticks call p.run(7) t=ticks-t destinationpicture=p.destinationpicture else // simple blur h(0) = 0.25 h(1) = 0.5 h(2) = 0.25 v(0) = 0.25 v(1) = 0.5 v(2) = 0.25 t=ticks destinationpicture = sourcepicture.convolution(h,v,7) t=ticks-t end if StaticText11.text=str(t) destination.refresh End EventHandler
End Control
Control PushButton5 Inherits PushButton
ControlInstance PushButton5 Inherits PushButton
EventHandler Sub Action() dim h(2),v(2) as double dim t as integer dim p as PictureConvolutionMBS // simple sharpen if CheckPlugin.Value then p=new PictureConvolutionMBS p.hor(0) = -0.25 p.hor(1) = 1.5 p.hor(2) = -0.25 p.ver(0) = -0.25 p.ver(1) = 1.5 p.ver(2) = -0.25 p.ValueCount=3 p.SourcePicture=sourcepicture t=ticks call p.run(7) t=ticks-t destinationpicture=p.destinationpicture else h(0) = -0.25 h(1) = 1.5 h(2) = -0.25 v(0) = -0.25 v(1) = 1.5 v(2) = -0.25 t=ticks destinationpicture = sourcepicture.convolution(h,v,7) t=ticks-t end if StaticText12.text=str(t) destination.refresh End EventHandler
End Control
Control PushButton6 Inherits PushButton
ControlInstance PushButton6 Inherits PushButton
EventHandler Sub Action() dim lut(16,16,16,2) as double dim r,g,b as integer dim t as integer dim surf as rgbSurface dim p as PictureLut3DMBS dim x,y as integer dim lutinput as picture if CheckPlugin.Value then p=new PictureLut3DMBS for r = 0 to 15 for g = 0 to 15 for b = 0 to 15 p.Table(r,g,b,0) = 255 - 17*r p.Table(r,g,b,1) = 255 - 17*g p.Table(r,g,b,2) = 255 - 17*b next next next p.SourcePicture=sourcepicture t=ticks call p.Run t=ticks-t destinationpicture=p.destinationpicture else for r = 0 to 15 for g = 0 to 15 for b = 0 to 15 lut(r,g,b,0) = 255 - 17*r lut(r,g,b,1) = 255 - 17*g lut(r,g,b,2) = 255 - 17*b next next next t=ticks destinationpicture = sourcepicture.lut3d(lut,checkdither.value) t=ticks-t end if StaticText13.text=str(t) destination.refresh End EventHandler
End Control
Control StaticText3 Inherits Label
ControlInstance StaticText3 Inherits Label
End Control
Control PushButton7 Inherits PushButton
ControlInstance PushButton7 Inherits PushButton
EventHandler Sub Action() dim lut(16,16,16,2) as double dim r,g,b as integer dim t as integer // selective pure red will be changed to blue, very primitive version dim p as PictureLut3DMBS if CheckPlugin.Value then p=new PictureLut3DMBS for r = 0 to 16 for g = 0 to 16 for b = 0 to 16 if r>g*2 and r>b*2 then p.table(r,g,b,0) = 15*b p.table(r,g,b,1) = 15*g p.table(r,g,b,2) = 15*r else p.table(r,g,b,0) = 15*r p.table(r,g,b,1) = 15*g p.table(r,g,b,2) = 15*b end next next next p.SourcePicture=sourcepicture t=ticks call p.run t=ticks-t destinationpicture=p.DestinationPicture else for r = 0 to 16 for g = 0 to 16 for b = 0 to 16 if r>g*2 and r>b*2 then LUT(r,g,b,0) = 15*b LUT(r,g,b,1) = 15*g LUT(r,g,b,2) = 15*r else LUT(r,g,b,0) = 15*r LUT(r,g,b,1) = 15*g LUT(r,g,b,2) = 15*b end next next next t=ticks destinationpicture = sourcepicture.lut3d(lut,checkdither.value) t=ticks-t end if StaticText14.text=str(t) destination.refresh End EventHandler
End Control
Control StaticText4 Inherits Label
ControlInstance StaticText4 Inherits Label
End Control
Control StaticText5 Inherits Label
ControlInstance StaticText5 Inherits Label
End Control
Control PushButton8 Inherits PushButton
ControlInstance PushButton8 Inherits PushButton
EventHandler Sub Action() dim p,pattern,src,dest as picture dim t as integer // let's do some compositing p = New Picture(source.width,source.height,32) p.graphics.forecolor = rgb(0,0,0) p.graphics.fillrect 0,0,p.width,p.height p.mask.graphics.clearrect 0,0,p.width,p.height pattern = New Picture(4*source.width,4*source.height,32) pattern.mask.graphics.clearrect 0,0,pattern.width,pattern.height pattern.mask.graphics.forecolor = rgb(0,0,0) pattern.mask.graphics.textsize = 256 pattern.mask.graphics.drawstring "title",pattern.width/2,pattern.height/2 pattern.mask.graphics.filloval 20, 20, 400, 400 // fill picture pattern.graphics.forecolor = rgb(255,255,255) pattern.graphics.fillrect 0,0,pattern.width,pattern.height p.graphics.drawpicture pattern,0,0,p.width,p.height,0,0,pattern.width,pattern.height // fill mask pattern.graphics.forecolor = rgb(0,0,0) pattern.graphics.fillrect 0,0,pattern.width,pattern.height p.mask.graphics.drawpicture pattern,0,0,p.width,p.height,0,0,pattern.width,pattern.height destinationpicture = New Picture (p.width,p.height,32) destinationpicture.graphics.drawpicture sourcepicture,0,0 sourcepicture.graphics.drawpicture p,0,0 source.refresh t=ticks destinationpicture.graphics.drawpicture p.unmultiply,0,0 t=ticks-t destination.refresh StaticText15.text=str(t) End EventHandler
End Control
Control PushButton9 Inherits PushButton
ControlInstance PushButton9 Inherits PushButton
EventHandler Sub Action() dim m,m2,m3 as memoryBlock dim x,y as integer dim offset as integer dim s,s3 as string dim surf as rgbSurface dim t as integer t=ticks m = newmemoryBlock(sourcepicture.width*sourcepicture.height*4) surf = sourcepicture.rgbSurface for x = 0 to sourcepicture.width-1 for y = 0 to sourcepicture.height-1 m.colorValue(offset,32) = surf.pixel(x,y) offset = offset + 4 next next s = m.stringValue(0,m.size) m2 = m.RunLengthEncode msgBox "Compressed " + format(m2.size/m.size,"0%") m3 = m2.RunLengthDecode s3 = m3.stringValue(0,m3.size) if strcomp(s,s3,0) = 0 then msgbox "Compression-Decompression succeeded" else msgbox "Compression-Decompression failed" end if destinationpicture = nil then destinationpicture = New Picture(sourcepicture.width,sourcepicture.height,32) end offset = 0 surf = destinationpicture.rgbSurface for x = 0 to destinationpicture.width-1 for y = 0 to destinationpicture.height-1 surf.pixel(x,y) = m.colorValue(offset,32) offset = offset + 4 next next t=ticks-t StaticText16.text=str(t) destination.refresh End EventHandler
End Control
Control PushButton11 Inherits PushButton
ControlInstance PushButton11 Inherits PushButton
EventHandler Sub Action() dim m(2,2) as double dim t as integer dim p as PictureMatrix3DMBS // matrix for identity if CheckPlugin.Value then p=new PictureMatrix3DMBS p.matrix(0,0) = 1 p.matrix(1,0) = 0 p.matrix(2,0) = 0 p.matrix(0,1) = 0 p.matrix(1,1) = 1 p.matrix(2,1) = 0 p.matrix(0,2) = 0 p.matrix(1,2) = 0 p.matrix(2,2) = 1 p.SourcePicture=sourcepicture t=Ticks call p.run t=ticks-t destinationpicture=p.DestinationPicture else m(0,0) = 1 m(1,0) = 0 m(2,0) = 0 m(0,1) = 0 m(1,1) = 1 m(2,1) = 0 m(0,2) = 0 m(1,2) = 0 m(2,2) = 1 t=ticks destinationpicture = sourcepicture.matrix3d(m) t=Ticks-t end if StaticText9.text=str(t) destination.refresh End EventHandler
End Control
Control PushButton10 Inherits PushButton
ControlInstance PushButton10 Inherits PushButton
EventHandler Sub Action() dim m(3,3) as double dim t as integer dim p as PictureMatrix3DMBS // matrix for invert uses if CheckPlugin.Value then p=new PictureMatrix3DMBS p.matrix(0,0) = -1 p.matrix(1,0) = 0 p.matrix(2,0) = 0 p.matrix(0,1) = 0 p.matrix(1,1) = -1 p.matrix(2,1) = 0 p.matrix(0,2) = 0 p.matrix(1,2) = 0 p.matrix(2,2) = -1 p.matrix(0,3) = 255 p.matrix(1,3) = 255 p.matrix(2,3) = 255 p.matrix(3,0) = 0 p.matrix(3,1) = 0 p.matrix(3,2) = 0 p.SourcePicture=sourcepicture t=Ticks call p.run t=ticks-t destinationpicture=p.DestinationPicture else m(0,0) = -1 m(1,0) = 0 m(2,0) = 0 m(0,1) = 0 m(1,1) = -1 m(2,1) = 0 m(0,2) = 0 m(1,2) = 0 m(2,2) = -1 m(0,3) = 255 m(1,3) = 255 m(2,3) = 255 t=ticks destinationpicture = sourcepicture.matrix3dwithConstants(m,checkdither.value) t=Ticks-t end if StaticText10.text=str(t) destination.refresh End EventHandler
End Control
Control StaticText6 Inherits Label
ControlInstance StaticText6 Inherits Label
End Control
Control StaticText7 Inherits Label
ControlInstance StaticText7 Inherits Label
End Control
Control StaticText8 Inherits Label
ControlInstance StaticText8 Inherits Label
End Control
Control StaticText9 Inherits Label
ControlInstance StaticText9 Inherits Label
End Control
Control StaticText10 Inherits Label
ControlInstance StaticText10 Inherits Label
End Control
Control CheckPlugin Inherits CheckBox
ControlInstance CheckPlugin Inherits CheckBox
End Control
Control StaticText11 Inherits Label
ControlInstance StaticText11 Inherits Label
End Control
Control StaticText12 Inherits Label
ControlInstance StaticText12 Inherits Label
End Control
Control StaticText13 Inherits Label
ControlInstance StaticText13 Inherits Label
End Control
Control StaticText14 Inherits Label
ControlInstance StaticText14 Inherits Label
End Control
Control StaticText15 Inherits Label
ControlInstance StaticText15 Inherits Label
End Control
Control StaticText16 Inherits Label
ControlInstance StaticText16 Inherits Label
End Control
Control CheckDither Inherits CheckBox
ControlInstance CheckDither Inherits CheckBox
End Control
EventHandler Sub Open() LoadPicture toni End EventHandler
Protected Sub LoadPicture(p as picture) if p<>nil then sourcepicture = New Picture(p.width,p.height,32) sourcepicture.graphics.drawpicture p,0,0,p.width,p.Height,0,0,p.width,p.height me.refresh pushButton1.enabled = true pushButton2.enabled = true pushButton3.enabled = true pushButton4.enabled = true pushButton5.enabled = true pushButton6.enabled = true pushButton7.enabled = true pushButton8.enabled = true pushButton9.enabled = true pushbutton10.enabled = true pushButton11.enabled = true end End Sub
Property Protected destinationpicture As picture
Property Protected sourcepicture As picture
End Class
MenuBar MenuBar1
MenuItem UntitledMenu1 = ""
MenuItem FileMenu = "&File"
MenuItem FileQuit = "Quit"
MenuItem EditMenu = "&Edit"
MenuItem EditUndo = "Undo"
MenuItem UntitledMenu0 = "-"
MenuItem EditCut = "Cut"
MenuItem EditCopy = "Copy"
MenuItem EditPaste = "Paste"
MenuItem EditClear = "Clear"
End MenuBar
Class App Inherits Application
End Class
Module ImageTransformations
Function Convolution(extends p as picture, hor() as double, ver() as double, channels as integer) As picture dim p2, intermediate, result as picture dim insurf,intermediatesurf, outsurf as rgbSurface dim x,y,w,h,r2,g2,b2,i,ub,ub2 as integer dim start, ende as integer dim c as color dim r,g,b as Double if p=nil then return nil end if // verify if picture has an rgbsurface insurf = p.rgbSurface if insurf = nil then p2 = New Picture(p.width,p.height,32) if p2<>nil then p2.graphics.drawpicture p,0,0 insurf = p2.rgbSurface end end intermediate = New Picture(p.width,p.height,32) if intermediate<>nil then intermediatesurf = intermediate.rgbSurface end result = New Picture(p.width,p.height,32) if result<>nil then outsurf = result.rgbSurface end if insurf = nil or intermediatesurf = nil or outsurf = nil then return nil end w = p.width-1 h = p.height-1 // borders will not be treated. if somebody want to get until the border, he can provide a larger picture. ub = ubound(hor) ub2 = ub\2 start = ub2 ende = w - ub2 for x = start to ende for y = 0 to h if bitwiseand(channels,1) = 1 then r = 0 for i = 0 to ub r = r + insurf.pixel(x-ub2+i,y).red * hor(i) next else r = insurf.pixel(x,y).red end if bitwiseand(channels,2) = 2 then g = 0 for i = 0 to ub g = g + insurf.pixel(x-ub2+i,y).green * hor(i) next else g = insurf.pixel(x,y).green end if bitwiseand(channels,4) = 4 then b = 0 for i = 0 to ub b = b + insurf.pixel(x-ub2+i,y).blue * hor(i) next else b = insurf.pixel(x,y).blue end intermediatesurf.pixel(x,y) = rgb(r,g,b) next next ub = ubound(ver) ub2 = ub/2 start = ub2 ende = h - ub2 for x = 0 to w for y = start to ende if bitwiseand(channels,1) = 1 then r = 0 for i = 0 to ub r = r + intermediatesurf.pixel(x,y-ub2+i).red * ver(i) next else r = intermediatesurf.pixel(x,y).red end if bitwiseand(channels,2)= 2 then g = 0 for i = 0 to ub g = g + intermediatesurf.pixel(x,y-ub2+i).green * ver(i) next else g = intermediatesurf.pixel(x,y).green end if bitwiseand(channels,4)= 4 then b = 0 for i = 0 to ub b = b + intermediatesurf.pixel(x,y-ub2+i).blue * ver(i) next else b = intermediatesurf.pixel(x,y).blue end outsurf.pixel(x,y) = rgb(r,g,b) next next return result End Function
Function LUT3d(extends p as picture, lut(,,,) as double, dither as boolean = false) As picture dim p2, result as picture dim insurf,outsurf as rgbSurface dim x,y,r,g,b,w,h,r2,g2,b2 as integer dim nx,ny,nz,nx1,ny1,nz1,i as integer dim rrest, grest, brest as double dim sxyz, fx,fy,fz as double // sxyz neu double! dim c as color // expects a LUT(16,16,16,2), eg 17 values in each dimension, which makes even steps from 0..15.30..255 if p=nil then return nil // verify if picture has an rgbsurface insurf = p.rgbSurface if insurf = nil then p2 = New Picture(p.width,p.height,32) if p2<>nil then p2.graphics.drawpicture p,0,0 insurf = p2.rgbSurface end end result = New Picture(p.width,p.height,32) if result<>nil then outsurf = result.rgbSurface end if insurf = nil or outsurf = nil then return nil end w = p.width-1 h = p.height-1 for y = 0 to h for x = 0 to w c = insurf.Pixel(x,y) r = c.red g = c.green b = c.blue nx = r \ 17 ny = g \ 17 nz = b \ 17 nx1 = min(nx+1,15) ny1 = min(ny+1,15) nz1 = min(nz+1,15) fx = (r mod 17) / 17.0 fy = (g mod 17) / 17.0 fz = (b mod 17) / 17.0 for i = 0 to 2 // tetraeder interpolation. // would probably be faster if each channel coded and not a for-loop if (fx > fy) then if (fy > fz) then Sxyz = (1.0-fx)* LUT( nx , ny , nz, i ) + (fx-fy)* LUT(nx1, ny , nz, i ) + (fy-fz)* LUT(nx1,ny1, nz, i ) + (fz)* LUT(nx1,ny1,nz1,i) elseif (fx > fz) then Sxyz = (1.0-fx)* LUT( nx , ny , nz, i ) + (fx-fz)* LUT(nx1, ny , nz, i ) + (fz-fy)* LUT(nx1, ny ,nz1, i) + (fy)* LUT(nx1,ny1,nz1,i) else Sxyz = (1.0-fz)* LUT( nx , ny , nz, i) + (fz-fx)* LUT( nx , ny ,nz1, i) + (fx-fy)* LUT(nx1, ny ,nz1,i)+ (fy)* LUT(nx1,ny1,nz1,i) end else if (fz > fy) then Sxyz = (1.0-fz)* LUT( nx , ny , nz,i ) + (fz-fy)* LUT( nx , ny ,nz1,i) + (fy-fx)* LUT( nx ,ny1,nz1,i) + (fx)* LUT(nx1,ny1,nz1,i) elseif (fz > fx) then Sxyz = (1.0-fy)* LUT( nx , ny , nz,i ) + (fy-fz)* LUT( nx ,ny1, nz ,i) + (fz-fx)* LUT( nx ,ny1,nz1,i) + (fx)* LUT(nx1,ny1,nz1,i) else Sxyz = (1.0-fy)* LUT( nx , ny , nz,i ) + (fy-fx)* LUT( nx ,ny1, nz ,i) + (fx-fz)* LUT(nx1,ny1, nz ,i) + (fz)* LUT(nx1,ny1,nz1,i) end end select case i case 0 if dither then r = r + rrest r = Sxyz rrest = Sxyz-r case 1 if dither then g = g + grest g = Sxyz grest = Sxyz-g case 2 if dither then b = b + brest b = Sxyz brest = Sxyz-b end next outsurf.pixel(x,y) = rgb(r,g,b) next next return result exception err as outofboundsException msgBox "matrix too small" End Function
Function Matrix3d(extends p as picture, m(,) as double, dither as boolean = false) As picture dim p2, result as picture dim insurf,outsurf as rgbSurface dim x,y,r,g,b,w,h,r2,g2,b2 as integer dim rd,gd,bd as double dim rrest, grest, brest as double dim c as color if p=nil then return nil // verify if picture has an rgbsurface insurf = p.rgbSurface if insurf = nil then p2 = New Picture(p.width,p.height,32) if p2<>nil then p2.graphics.drawpicture p,0,0 insurf = p2.rgbSurface end end result = New Picture(p.width,p.height,32) if result<>nil then outsurf = result.rgbSurface end if insurf = nil or outsurf = nil then return nil end w = p.width-1 h = p.height-1 for x = 0 to w for y = 0 to h c = insurf.pixel(x,y) r = c.red g = c.green b = c.blue rd = m(0,0)*r + m(1,0)*g + m(2,0)*b gd = m(0,1)*r + m(1,1)*g + m(2,1)*b bd = m(0,2)*r + m(1,2)*g + m(2,2)*b if dither then rd = rd + rrest r2 = rd rrest = rd -r2 gd = gd + grest g2 = gd grest = gd -g2 bd = bd + brest b2 = bd brest = bd -b2 else r2 = rd g2 = gd b2 = bd end outsurf.pixel(x,y) = rgb(r2,g2,b2) next next return result exception err as outofboundsException msgBox "matrix too small" End Function
Function Matrix3dwithConstants(extends p as picture, m(,) as double, dither as boolean = false) As picture dim p2, result as picture dim insurf,outsurf as rgbSurface dim x,y,r,g,b,w,h,r2,g2,b2 as integer dim rd,gd,bd,rrest,grest,brest as double dim c as color if p=nil then return nil // verify if picture has an rgbsurface insurf = p.rgbSurface if insurf = nil then p2 = New Picture(p.width,p.height,32) if p2<>nil then p2.graphics.drawpicture p,0,0 insurf = p2.rgbSurface end end result = New Picture(p.width,p.height,32) if result<>nil then outsurf = result.rgbSurface end if insurf = nil or outsurf = nil then return nil end w = p.width-1 h = p.height-1 for x = 0 to w for y = 0 to h c = insurf.pixel(x,y) r = c.red + m(0,3) g = c.green + m(1,3) b = c.blue + m(2,3) rd = m(0,0)*r + m(1,0)*g + m(2,0)*b + m(3,0) gd = m(0,1)*r + m(1,1)*g + m(2,1)*b + m(3,1) bd = m(0,2)*r + m(1,2)*g + m(2,2)*b + m(3,2) if dither then rd = rd + rrest r2 = rd rrest = rd -r2 gd = gd + grest g2 = gd grest = gd -g2 bd = bd + brest b2 = bd brest = bd -b2 else r2 = rd g2 = gd b2 = bd end outsurf.pixel(x,y) = rgb(r2,g2,b2) next next return result exception err as outofboundsException msgBox "matrix too small" End Function
Function RunLengthDecode(extends m as memoryBlock) As memoryBlock // must be dynamically resized. we start with 2 times the length dim i,j as integer dim count as integer dim test,b as integer dim st as string dim run as boolean dim moffset, resultoffset as integer dim result as memoryBlock dim s as integer result = newmemoryBlock(m.size*2) //Loop until you get the number of unpacked bytes you are expecting: // Read the next source byte into n. // If n is between 0 and 127 inclusive, copy the next n+1 bytes literally. // Else if n is between -127 and -1 inclusive, copy the next byte -n+1 times. //Else if n is -128, noop. // Endloop //-127 signed char is 129 unsigned char s = m.size for i = 0 to s-1 test = m.byte(moffset) moffset = moffset + 1 if test>=0 and test<=127 then st = m.stringValue(moffset,test+1) moffset = moffset + test + 1 if result.size < resultoffset + test + 1 then result.size = resultoffset + test + 1 end result.stringValue(resultoffset,test+1) = st resultoffset = resultoffset + test + 1 elseif test = 128 then // nop else test = test - 256 // make signed b = m.byte(moffset) moffset = moffset + 1 if result.size < resultoffset - test + 1 then result.size = resultoffset - test + 1 end for j = 1 to -test + 1 result.byte(resultoffset) = b resultoffset = resultoffset + 1 next end i = moffset next result.size = resultoffset return result End Function
Function RunLengthEncode(extends m as memoryBlock) As memoryBlock // Decode: //Loop until you get the number of unpacked bytes you are expecting: // Read the next source byte into n. // If n is between 0 and 127 inclusive, copy the next n+1 bytes literally. // Else if n is between -127 and -1 inclusive, copy the next byte -n+1 times. //Else if n is -128, noop. // Endloop //-127 signed char is 129 unsigned char // worst case: result is 128/127 + 1 byte longer dim i as integer dim count as integer dim test,old,oldold as integer dim st as string dim run as boolean dim moffset, resultoffset as integer dim result as memoryBlock dim s as integer result = newmemoryBlock(m.size*128/127+1) //test with declare // this is a toolbox function in mac, but i never got it working. 'dim memIn,memOut as memoryblock ' 'if s = 0 then 'return 'end ' 'memIn = newmemoryBlock(s) 'for i = 0 to s-1 'memin.byte(i) = m.readbyte 'next 'memOut = newmemoryBlock(s+(s+126)/127) ' 'Declare Sub PackBits Lib "InterfaceLib" (srcPtr as Ptr, dstPtr as Ptr, srcBytes as Integer) ' 'PackBits memIn,memOut,s ' 'for i = 0 to s+(s+126)/127-1 ' 'next ' 'return test=-1 old = -1 oldold=-1 count = -1 run = false st="" s = m.size for i = 0 to s-1 test = m.byte(moffset) moffset = moffset + 1 if run then if test = old then count = count -1 if count = 129 then result.byte(resultoffset) = count resultoffset = resultoffset + 1 result.byte(resultoffset) = test resultoffset = resultoffset + 1 run = false test = -1 count = -1 st = "" end if else result.byte(resultoffset) = count resultoffset = resultoffset + 1 result.byte(resultoffset) = old resultoffset = resultoffset + 1 run = false count = 0 st =chrb(test) end if else if test = old and test = oldold then if count > 1 then result.byte(resultoffset) = count-2 resultoffset = resultoffset + 1 result.stringvalue(resultoffset,lenb(st)) = st resultoffset = resultoffset + lenb(st) resultoffset = resultoffset - 2 // last 2 bytes are wrong end if run = true count = 254 st ="" else st = st + chrb(test) count = count + 1 if count = 127 then result.byte(resultoffset) = count resultoffset = resultoffset + 1 result.stringvalue(resultoffset,lenb(st)) = st resultoffset = resultoffset + lenb(st) run = false test = -1 count = -1 st = "" end if end if end if oldold = old old = test next if count >-1 then if run then result.byte(resultoffset) = count resultoffset = resultoffset + 1 result.byte(resultoffset) = test resultoffset = resultoffset + 1 else result.byte(resultoffset) = count resultoffset = resultoffset + 1 result.stringvalue(resultoffset,lenb(st)) = st resultoffset = resultoffset + lenb(st) end if end if result.size = resultoffset return result End Function
Function Unmultiply(extends p as picture) As picture dim p2, maskpicture, result as picture dim insurf,masksurf,outsurf as rgbSurface dim x,y,r,g,b,m,w,h as integer dim c as color if p=nil then return nil // verify if picture has an rgbsurface insurf = p.rgbSurface if insurf = nil then p2 = New Picture(p.width,p.height,32) if p2<>nil then p2.graphics.drawpicture p,0,0 insurf = p2.rgbSurface end else p2 = p end maskpicture = p2.mask masksurf = maskpicture.rgbsurface result = New Picture(p.width,p.height,32) if result<>nil then outsurf = result.rgbSurface end if insurf = nil or masksurf = nil or outsurf = nil then return nil end w = p.width-1 h = p.height-1 for x = 0 to w for y = 0 to h c = insurf.pixel(x,y) r = c.red g = c.green b = c.blue m = 255-masksurf.pixel(x,y).green if m > 0 then r = r * 255 / m g = g * 255 / m b = b * 255 / m end outsurf.pixel(x,y) = rgb(r,g,b) next next result.mask.graphics.drawpicture maskpicture,0,0 return result End Function
Note "About PictureConvolutionMBS"
Class PictureConvolutionMBS Filter a picture using a custom defined horizontal and vertical convolution. A conviolution is a filter window applied iteratively over the pixels. Convolution filtering is a basic image-processing function used for applications like blurring, sharpening, edge detection and resampling. The filters are provides to the plugin as arrays of doubles. If the sum of the values is not 1, then the resulting picture will be darker or brighter. The border pixels (filtersize/2) will not be processed but return white. If you need the filter until the border, then you need to provide a larger picture with either a black border or the last pixel repeated, whatever is more appropriate for you. Properties: - Hor() as double : filter set for horizontal filtering. - Ver() as double : filter set for vertical filtering - MaxX ?? - MaxY ?? - MinX ?? - MinY ?? - sourcePicture as Picture - destinationPicture as Picture Methods: - Run : transform the sourcePicture into the destinationPicture - Close
Note "About PictureLut3dMBS"
Class PictureLut3dMBS Color correction of a picture using a three-dimensional lookup table. Lookup tables are used to speed up color corrections of an image. A three-dimensional lookup table can modelise any correction and even corrections based on experimental data, where no mathematical model is available. To be efficient, the lookup table cannot contain all values (17 million), but only some values in a regular grid. The values are then interpolated. If you retain the corner values 0 and 255, there is a limited number of possible grid sizes, all of which must be dividers of 255. We retain a table with 16*16*16 values which gives a good interpolation while keeping the size of the table small. Properties: - Table(15,15,15,2) as Double : look up table. The dimesions define red, green, blue and the channel. - MaxX ?? - MaxY ?? - MinX ?? - MinY ?? - sourcePicture as Picture - destinationPicture as Picture - dither as Boolean : dither rounding errors to avoid stepping artefacts Methods: - Run : transform the sourcePicture into the destinationPicture - Close
Note "About PictureMatrix3DMBS"
Class PictureMatrix3dMBS Transformation of a picture in the RGB color space. Each new color is defined as a linear combination of the old color. This transformation can be used to make a picture gray or tinted or to transform the picture into another color space like the video component space. The matrix (0,0) - (2,2) define the multiplication factors. The vector (0,3) - (2,3) defines the constants added before the multiplication to the source channel. The vector (3,0) - (3,2) defines the constants added after the multiplication to the source channel. The value (3,3) is unused. Red, for example, is calculated using the following formula: red = Matrix(0,0)*(r+Matrix(0,3)) + Matrix(1,0)*(g+Matrix(1,3)) + Matrix(2,0)*(b+Matrix(2,3)) + Matrix(3,0) Properties: - Matrix(3,3) as Double : - MaxX ?? - MaxY ?? - MinX ?? - MinY ?? - sourcePicture as Picture - destinationPicture as Picture - dither as Boolean : dither rounding errors to avoid stepping artefacts Methods: - Run : transform the sourcePicture into the destinationPicture - Close
End Module
ExternalFile toni
End ExternalFile
End Project

See also:

Feedback, Comments & Corrections

The items on this page are in the following plugins: MBS Picture Plugin.




Links
MBS Xojo Chart Plugins