Notifications
Clear all

[Closed] dotNet to simulate Paint tool for Bitmap

thanks, I’ve already seen the tutorial about “paint event”, it create the image when rollout open, but I want to load images after, in second moment, and i don’t want that the file are saved in a temporaney bmp file.
In Maxscript you can utilize a internal bitmap value, (but i must save in bmp to show the texture map )

hi john,

to avoid saving to a temporary bitmap, try saving the max bitmap to the clipboard using setclipboardbitmap <bitmap> and then using (dotnetclass “clipboard”).getimage() to retrieve it in the dotnetcontrol

you can also use Paul’s advice on using GDI+ to draw the temp image to an ‘in-memory’ dotnet image, like how you mentioned.

Perfect!! is a very good idea. Now the script can load in the pixtureBox a maxscript bitmap, i make this code:

	on ChList selected index do
	(
		chanel = index
		if TGA!=undefined then
		(
			paintPath.bitmap = TGA[index]
			btnCreate.caption = "create_ch:" + chanel as string
			-------------------------dotnet-------------
			setclipboardBitmap TGA[index]
			clipboardClass = dotNetClass "System.Windows.Forms.Clipboard"
			theImage = clipboardClass.getImage()
			--clipboardClass.setImage theImage
			--dnBitmap = getclipboardBitmap()
			dnPictureBox.image = dotnetObject "System.Drawing.Image" theImage
		)
	)

Now i can create some function like Windows Paint

Hi john,

That looks the ticket – the only thing you might want to look at s that you’re declaring the image twice. There’s no need to retrieve the clipboard and pass it to a dotnet image constructor, as it is already one. You can call the picturebox’s image function with the clipboard.getiimage() call to bypass this step. For the tool that you want to make it would be a good idea to keep it as optimised as possible to keep performance as high as possible.

1 Reply
(@johnwhile)
Joined: 11 months ago

Posts: 0

sorry but DotNet for me is a esoteric things and i don’t understand very well.
Do you mean : ?

	on ChList selected index do
	(
		chanel = index
		if TGA!=undefined then
		(
			btnCreate.caption = "create_ch:" + chanel as string
			setclipboardBitmap TGA[index]
			clipboardClass = dotNetClass "System.Windows.Forms.Clipboard"
			dnPictureBox.image = dotnetObject "System.Drawing.Image" (clipboardClass.getImage())
		)
	)

hi john,

pretty much, you just don’t need the image constructor. if you see what each function returns, you’ll see that you can pass the dotnet bitmap from the clipboard to the picturebox image property.

clipboardClass = dotNetClass "Clipboard"			
dotNetClass:System.Windows.Forms.Clipboard
b = bitmap 50 50 color:red
BitMap:
setclipboardBitmap b
true
clipboardClass.containsimage()
true
img = clipboardClass.getImage()
dotNetObject:System.Drawing.Bitmap
show img
  .Flags : <System.Int32>, read-only
  .FrameDimensionsList : <System.Guid[]>, read-only
  .Height : <System.Int32>, read-only
  .HorizontalResolution : <System.Single>, read-only
  .Palette : <System.Drawing.Imaging.ColorPalette>
  .PhysicalDimension : <System.Drawing.SizeF>, read-only
  .PixelFormat : <System.Drawing.Imaging.PixelFormat>, read-only
  .PropertyIdList : <System.Int32[]>, read-only
  .PropertyItems : <System.Drawing.Imaging.PropertyItem[]>, read-only
  .RawFormat : <System.Drawing.Imaging.ImageFormat>, read-only
  .Size : <System.Drawing.Size>, read-only
  .Tag : <System.Object>
  .VerticalResolution : <System.Single>, read-only
  .Width : <System.Int32>, read-only
true
rollout u "" width:162 height:162
(
	local clipboardClass = dotNetClass "Clipboard"
	
	dotnetcontrol pb1 "picturebox" pos:[6,5] width:150 height:122
	button btn1 "Bitmap > Image" pos:[6,134] width:149 height:22
	
	on u open do pb1.sizemode = pb1.sizemode.CenterImage
	
	on btn1 pressed do 
	(
		b = bitmap 50 50 color:red
		setclipboardBitmap b
		pb1.image = if clipboardClass.containsimage() then clipboardClass.getImage()
	)
)
createdialog u

so in your case, you could use

	(
		chanel = index
		if TGA!=undefined then
		(
			btnCreate.caption = "create_ch:" + chanel as string
			setclipboardBitmap TGA[index]
			clipboardClass = dotNetClass "Clipboard"			
			dnPictureBox.image = if clipboardClass.containsimage() then clipboardClass.getImage()
		)
	)

thanks a lot !!
Now I will try to edit the images (zoom, palette, etc …) and I will ask you other things =)

Ok, now i have tried to create a zoom, the idea is preserve the original Bitmap (TGA[n]) and paint only a new Bitmap with reside dimension.
But now, how i can change the view with scrool bar ? and you think is a good way of my script to build a similar-Paint tool or i must build other version ?


 -- TGA array = #(Bitmap ,Bitmap , ... )
 Local clipboardClass = dotNetClass "Clipboard"	
 Local Chanel= 1
 Local ZoomFactor = 1
 
 rollout PathRollout "PathFinding Editor" width:512 height:440
 (
 [i]	dotNetControl dnPictureBox "pictureBox" pos:[0,0] width:392 height:408[/i]
 
 	fn mesh_filter obj = superclassof obj == GeometryClass
 [i]	fn resizeImageDisplayed zf =
 	(
 		format "image = % x %
" dnPictureBox.image.Width dnPictureBox.image.Height
 		TGAzoom = bitmap (TGA[chanel].width * ZoomFactor) (TGA[chanel].height * ZoomFactor)
 		copy TGA[chanel] TGAzoom 
 		setclipboardBitmap TGAzoom		
 		dnPictureBox.image = if clipboardClass.containsimage() then clipboardClass.getImage()
 	)[/i]
 	bitmap paintPath "MaxScript Bmp" pos:[424,304] width:80 height:80
 	button btnDraw "PaintObj" pos:[416,272] width:48 height:24 enabled:false
 	pickbutton btnPick "Add" pos:[464,272] width:40 height:24 --filter:mesh_filter
 	dropdownList ChList "Show by channel" pos:[416,8] width:88 height:40 items:#("no-channel")
 	button btnCreate "<create>" pos:[416,56] width:64 height:16 enabled:false
 	listbox lbxPlaneList "Object Used" pos:[416,88] width:88 height:12
 	progressBar ProgBar "ProgressBar" pos:[408,393] width:104 height:15
 [i]	button btnZoomUp "Zoom[+]" pos:[280,408] width:56 height:24
 	button btnZoomDown "Zoom[-]" pos:[336,408] width:56 height:24[/i]
 	
 [i]	on btnZoomUp pressed do
 	(
 		ZoomFactor*=2.0
 		resizeImageDisplayed ZoomFactor
 	)[/i]
 [i]	on btnZoomDown pressed do
 	(
 		ZoomFactor/=2.0
 		resizeImageDisplayed ZoomFactor
 	)[/i]
 [i]	on PathRollout open do
 	(
 		dnPictureBox.backColor=(dotNetClass "system.drawing.color").gray
 		dnPictureBox.Dock = dotNetClass "DockStyle.Fill"
 		dnPictureBox.BorderStyle = dotNetClass "BorderStyle.FixedSingle"
 		dnPictureBox.SizeMode = dotNetClass "PictureBoxSizeMode.Zoom"
 		
 		dnVScrollBar = dotNetObject "VScrollBar"
 		dnHScrollBar = dotNetObject "HScrollBar"
 		dnPictureBox.Controls.AddRange #(dnVScrollBar,dnHScrollBar)
 		--
 		dnVScrollBar.Dock = dotNetClass "DockStyle.Right"
 		dnVScrollBar.Location = dotNetObject "Drawing.Point" (392-16) 0
 		dnVScrollBar.size = dotNetObject "Drawing.Size" 16 392
 		--
 		dnHScrollBar.Dock = dotNetClass "DockStyle.Bottom"
 		dnHScrollBar.Location = dotNetObject "Drawing.Point"  0 392
 		dnHScrollBar.size = dotNetObject "Drawing.Size" (392-16) 16
 		
 		print dnPictureBox.Bottom
 		print dnPictureBox.Right
 
 	)[/i]
 	on btnDraw pressed do
 	(
 		if paintPath.bitmap!= undefined then
 		(
 			thePlane[chanel].material = Standard diffusemap:(bitmapTexture filename:(getFileName chanel))
 			showTextureMap thePlane[chanel].material true
 		)
 		else messageBox "Invalid : no bitmap image loaded !"
 	)
 	on btnPick picked obj do
 	(
 		ListArray = for i=1 to lbxPlaneList.items.count where (getNodeByName  lbxPlaneList.items[i])!=undefined collect  lbxPlaneList.items[i]
 		lbxPlaneList.items = ListArray
 		if obj!=undefined then
 		(
 			thePlane[chanel] = obj
 			btnDraw.enabled = true
 		)
 		append ListArray obj.name
 		lbxPlaneList.items = ListArray
 	)
 	on ChList selected index do
 	(
 		chanel = index
 		if TGA!=undefined then
 		(
 			isEnabled  = true
 			btnCreate.caption = "create_ch:" + chanel as string
 			setclipboardBitmap TGA[index]		
 			dnPictureBox.image = if clipboardClass.containsimage() then clipboardClass.getImage()
 			--if isChecked do zooming 10.0
 		)
 	)
 	on btnCreate pressed do
 	(
 		img = TGA[chanel]
 		setTempBmpFile img chanel
 		obj =plane realWorldMapSize:false width:( img.width*2) length:( img.height*2) widthsegs:1 lengthsegs:1 transform:(matrix3 [-1,0,0] [0,1,0] [0,0,1] [0,0,0]) name =("channel_" + ch as string)	
 		obj.material = Standard diffusemap: (bitmapTexture filename:(getFileName chanel))
 		showTextureMap obj.material true
 		thePlane[chanel] = obj
 	)
 )
 createDialog PathRollout menu:theMenu
 )

i make a little experiments but when i try to sroll the scroll bars the bitmap are demaged…

rollout PathRollout "PathFinding Editor" width:512 height:440
(
	dotNetControl dnPictureBox "pictureBox" pos:[0,0] width:392 height:392
	dotNetControl dnVScrollBar "VScrollBar" pos:[392,0] width:16 height:392
	dotNetControl dnHScrollBar "HScrollBar" pos:[0,392] width:392 height:16
	fn mesh_filter obj = superclassof obj == GeometryClass
	fn moveImage =
	(
		dnPictureBox.Left = -dnHScrollBar.Value
		dnPictureBox.Top = -dnVScrollBar.Value
		dnPictureBox.Update()
	)
	fn resizeImageDisplayed zf =
	(
		img = TGA[chanel]
		pbWidth = dnPictureBox.Width
		pbHeight = dnPictureBox.Height
		newWidth = img.width * ZoomFactor
		newHeight = img.height * ZoomFactor
		
		newTGA = bitmap newWidth newHeight
		copy img newTGA
		setclipboardBitmap newTGA	
		dnPictureBox.image = if clipboardClass.containsimage() then clipboardClass.getImage()
		
		
		dnVScrollBar.Maximum = newWidth-pbWidth
		dnHScrollBar.Maximum = newHeight-pbHeight

		--format "large:% ; small:% ; max:%
" dnVScrollBar.LargeChange dnVScrollBar.SmallChange dnVScrollBar.Maximum
	)
	bitmap paintPath "MaxScript Bmp" pos:[424,304] width:80 height:80
	button btnDraw "PaintObj" pos:[416,272] width:48 height:24 enabled:false
	pickbutton btnPick "Add" pos:[464,272] width:40 height:24 --filter:mesh_filter
 --filter:mesh_filter
	dropdownList ChList "Show by channel" pos:[416,8] width:88 height:40 items:#("no-channel")
	button btnCreate "<create>" pos:[416,56] width:64 height:16 enabled:false
	listbox lbxPlaneList "Object Used" pos:[416,88] width:88 height:12
	progressBar ProgBar "ProgressBar" pos:[408,393] width:104 height:15
	button btnZoomUp "Zoom[+]" pos:[280,408] width:56 height:24
	button btnZoomDown "Zoom[-]" pos:[336,408] width:56 height:24
	
	on dnVScrollBar ValueChanged EventArgs do
	(
		--format "Vscrool.Value=%
" dnVScrollBar.value
		moveImage()
	)
	on dnHScrollBar ValueChanged EventArgs do
	(
		--format "Hscrool.Value=%
" dnHScrollBar.value
		moveImage()
	)
	on PathRollout open do
	(
		dnPictureBox.backColor=(dotNetClass "system.drawing.color").gray

	)
	on btnDraw pressed do
	(
		if paintPath.bitmap!= undefined then
		(
			thePlane[chanel].material = Standard diffusemap:(bitmapTexture filename:(getFileName chanel))
			showTextureMap thePlane[chanel].material true
		)
		else messageBox "Invalid : no bitmap image loaded !"
	)
	on btnPick picked obj do
	(
		ListArray = for i=1 to lbxPlaneList.items.count where (getNodeByName  lbxPlaneList.items[i])!=undefined collect  lbxPlaneList.items[i]
		lbxPlaneList.items = ListArray
		if obj!=undefined then
		(
			thePlane[chanel] = obj
			btnDraw.enabled = true
		)
		append ListArray obj.name
		lbxPlaneList.items = ListArray
	)
	on ChList selected index do
	(
		chanel = index
		if TGA!=undefined then
		(
			isEnabled  = true
			btnCreate.caption = "create_ch:" + chanel as string
			setclipboardBitmap TGA[index]		
			dnPictureBox.image = if clipboardClass.containsimage() then clipboardClass.getImage()
			--if isChecked do zooming 10.0
		)
	)
	on btnCreate pressed do
	(
		img = TGA[chanel]
		setTempBmpFile img chanel
		obj =plane realWorldMapSize:false width:( img.width*2) length:( img.height*2) widthsegs:1 lengthsegs:1 transform:(matrix3 [-1,0,0] [0,1,0] [0,0,1] [0,0,0]) name =("channel_" + ch as string)	
		obj.material = Standard diffusemap: (bitmapTexture filename:(getFileName chanel))
		showTextureMap obj.material true
		thePlane[chanel] = obj
	)
	on btnZoomUp pressed do
	(
		ZoomFactor*=2.0
		resizeImageDisplayed ZoomFactor
	)
	on btnZoomDown pressed do
	(
		ZoomFactor/=2.0
		resizeImageDisplayed ZoomFactor
	)
)
createDialog PathRollout menu:theMenu
)

 
Page 2 / 2