Jump to content

[Request] Drawing Bot


x5tek
 Share

Recommended Posts

Hello, i am new and this is my first post.

I am sort of confsued of autoit; is there any posibility to make a drawing bot. That recieves some .bmp/.jpeg etc. files and then drawing it in a box we select. I want one to use with www.iscribble.net please!

Oh, if i gotta insert any link of the draw etc. heres what i wanna it to draw:

http://www.3dm3.com/tutorials/car3/blueprint.jpg

And eventualy having a box where to type a link to a picture to be easier. Or anything else, just to be a drawing bot!

Please, can someone help me?

Link to comment
Share on other sites

Hello, i am new and this is my first post.

I am sort of confsued of autoit; is there any posibility to make a drawing bot. That recieves some .bmp/.jpeg etc. files and then drawing it in a box we select. I want one to use with www.iscribble.net please!

Oh, if i gotta insert any link of the draw etc. heres what i wanna it to draw:

http://www.3dm3.com/tutorials/car3/blueprint.jpg

And eventualy having a box where to type a link to a picture to be easier. Or anything else, just to be a drawing bot!

Please, can someone help me?

I think that maybe you asking rather a lot, but welcome to the AutoIt forums :)

Do you mean actually draw the image as though it's being drawn with a pencil, or do you mean just copy the image?

If you mean draw as with a pencil then I have a script which will scan an image, calculate the lines and then draw the sahpe. The result is like this -

post-3602-1234296189_thumb.png

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

I think that maybe you asking rather a lot, but welcome to the AutoIt forums :)

Do you mean actually draw the image as though it's being drawn with a pencil, or do you mean just copy the image?

If you mean draw as with a pencil then I have a script which will scan an image, calculate the lines and then draw the sahpe. The result is like this -

post-3602-1234296189_thumb.png

If you mean like this:

http://www.youtube.com/watch?v=o3p8M66HpZc

Yes! Please give me the script and tell me how to use it...

Link to comment
Share on other sites

  • Moderators

We don't give things on this forum.

You attempt.

You fail.

You show failing code.

We try to help you to understand why it's failing.

Otherwise, you pay for someone to write it for you.... and that would be somewhere like rent-a-coder

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

We don't give things on this forum.

You attempt.

You fail.

You show failing code.

We try to help you to understand why it's failing.

Otherwise, you pay for someone to write it for you.... and that would be somewhere like rent-a-coder

Then how am i supposed to get a code like that? If he already haves it i dont think it would be too hard to give it to me... i think... And i dont know coding...

Also i taught autoit forums will be helpful.

Edited by x5tek
Link to comment
Share on other sites

  • Moderators

And i dont know coding...

I wasn't explicitly talking about the reference to his script, I was talking about the topic in general.

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

  • Moderators

I do not know what you mean...

I explained it in post one.

We are not a "give" or "request" to be given forum.

We are a "RTFM" type forum. Make an attempt, fail at the attempt, post the code that failed, receive help.

If Martin wants to share his code, then fine, but it's your responsibility to understand it, not his to hold your hand to... unless you want to pay him too.

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

I explained it in post one.

We are not a "give" or "request" to be given forum.

We are a "RTFM" type forum. Make an attempt, fail at the attempt, post the code that failed, receive help.

If Martin wants to share his code, then fine, but it's your responsibility to understand it, not his to hold your hand to... unless you want to pay him too.

Ok, I dont like the thing that this is not give or request forum......

Link to comment
Share on other sites

  • Moderators

Ok, I dont like the thing that this is not give or request forum......

So, if your boss (assuming you have one) requested you work the next two weeks for free, you'd like that?

Seriously x5tek, I'm not trying to set you up for failure here, but for success. Anything anyone does for you is out of the kindness of their hearts, and the fact they have time for you.

This board has been successful different levels of coders for years using this method.... and many (including myself) started with zero coding ability...

You'll find plenty of help on this forum (more so than any other), but you have to show the initiative and willingness to learn as well. You can't expect or hope to get anything for free here.

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

So, if your boss (assuming you have one) requested you work the next two weeks for free, you'd like that?

Seriously x5tek, I'm not trying to set you up for failure here, but for success. Anything anyone does for you is out of the kindness of their hearts, and the fact they have time for you.

This board has been successful different levels of coders for years using this method.... and many (including myself) started with zero coding ability...

You'll find plenty of help on this forum (more so than any other), but you have to show the initiative and willingness to learn as well. You can't expect or hope to get anything for free here.

Ok, i understand now, also this made my heart cry... Thanks, oh and im not even a teen [i belive by saying this ill get a ban? As i know the forum i THINK it is over 13 age, im 12] in conclusion i don't got a boss... Edited by x5tek
Link to comment
Share on other sites

Ok, i understand now, also this made my heart cry... Thanks, oh and im not even a teen [i belive by saying this ill get a ban? As i know the forum i THINK it is over 13 age, im 12] in conclusion i don't got a boss...

Well I showed a very similar script in another thread so it's no big deal to show it here.

But note

A. It takes a very long time to scan the image and work out how top draw the lines. The drawing of a the car you gave a link to took over 2 hours for my script to analyse before it started drawing it! I added a message box to warn you it is about to start drawing so you can just leave it running if you want to see it deal with a big image, then click ok to watch it draw. Try it out on something smaller. An image 200 x 200 will take only a few seconds. The script needs developing to make it faster.

B. The image needs to have a good contrast, ideally monochrome. Solid areas will be converted to outlines.

C. the drawing can be made faster by changing a sleep somewhere.

D. The lines generated could be saved to a file so that the image can be drawn any time without having to scan the image again.

E. Not much in the way of comments or explanation.

F. I'm not very interested in developing it at the moment, but anyone is welcome to do what they want with it.

You need the pencil image pencil.bmp

(I found it fascinating to watch it draw something complicated though.)

CODE

#cs ----------------------------------------------------------------------------

Author: A Greencan wrote the original scanning method used to find edges

see http://www.autoitscript.com/forum/index.ph...=86879&st=0

rest by martin, incluind scanning again at right angles, working out lines and shapes

and producing th edrawing

1. Select an image. It must be monchrome with a good contrast, preferably 256 bit colour at most

Very slow! The bigger the image the longer it takes in proportion to the square of the area!

A 300 x 200

Could be made very much faster but I lost interest in this script.

#ce ----------------------------------------------------------------------------

#NoTrayIcon

#include <GDIPlus.au3>

#include <WinAPI.au3>

#include <GuiConstantsEx.au3>

#include <WindowsConstants.au3>

#include <Misc.au3>

#include <Array.au3>

#include <StaticConstants.au3>

#include <Date.au3>

Global $Debugging = False

Global $REducedby = 0

Global $toofar = 40

Global Const $WS_EX_COMPOSITED = 0x2000000

$ImageName = FileOpenDialog("Select a Black & White image to be processed", @ScriptDir & "\", "Images (*.jpg;*.bmp)|All Files(*.*)", 1)

If @error Then

MsgBox(0, "", "No File chosen", 3)

Exit

EndIf

Local $ChangeText[2] = ['Black', 'White']

$Erase_White = false

_GDIPlus_Startup()

$hImage = _GDIPlus_ImageLoadFromFile($ImageName)

Opt("GUICloseOnESC", 1)

; get width and height of the image

Dim $iY, $iX

$iX = _GDIPlus_ImageGetWidth($hImage)

$iY = _GDIPlus_ImageGetHeight($hImage)

_GDIPlus_ImageDispose($hImage)

_GDIPlus_Shutdown()

Opt("PixelCoordMode", 2)

$hGUI = GUICreate("Image", $iX, $iY + 55, (@DesktopWidth - $iX) / 2, (@DesktopHeight - $iY) / 2, -1, $WS_EX_TOPMOST)

; and load the B/W image

GUICtrlCreatePic($ImageName, 0, 0, $iX, $iY)

$lab = GUICtrlCreateLabel("", 0, $iY + 2, $iX - 4, 36)

$Prog = GUICtrlCreateProgress(10,$iY+38,$iX-20)

GUISetState()

; make sure that the window is on top of all others

WinSetOnTop("Image", "", 1)

; Loop through the image and make an array of the white pixels because these are the ones that need to re-appear

Dim $PictArray[2 * ($iX + $iY)][3]

$iPA = 0

GUICtrlSetData($lab, "Scanning for edge points")

Opt("PixelCoordMode", 2)

; now scan the image

For $aY = 1 To $iY ; for each row

$previous_pixel = False

For $aX = 0 To $iX - 1 ; for each column

$Pixel_color = PixelGetColor($aX, $aY)

;If ($Erase_White = True And $Pixel_color > 16610000) Or ($Erase_White = False And $Pixel_color < 16610000) Then; almost white

If ($Erase_White = True And $Pixel_color > 0x888888) Or ($Erase_White = False And $Pixel_color <= 0x888888) Then; almost white

;~ If $Pixel_color < 100000 Then ; almost black use thi if you want to remove the oposite color

If $previous_pixel = False Then

$first_pixel = $aX

$previous_pixel = True

EndIf

Else ; All other colors are considered as white, this is suposed to be a black and white image!

If $previous_pixel = True Then ; OK previous was a black area

$previous_pixel = False ; reset flag

; now fill the array

; parameters

; $nLeftRect - Specifies the x-coordinate of the upper-left corner of the region in logical units.

; $nTopRect - Specifies the y-coordinate of the upper-left corner of the region in logical units.

; $nRightRect - Specifies the x-coordinate of the lower-right corner of the region in logical units.

; $nBottomRect - Specifies the y-coordinate of the lower-right corner of the region in logical units.

;_ArrayAdd($PictArray, String($first_pixel) & "," & String($aY) & "," & String($aX - 1) & "," & String($aY))

AddNewPoints($first_pixel, $aY, $aX - 1, $aY, $iPA, $PictArray)

EndIf

EndIf

Next

; this is needed for last pixel being white

If $previous_pixel = True Then ; OK previous was a black area

$previous_pixel = False ; reset flag

AddNewPoints($first_pixel, $aY, $aX - 1, $aY, $iPA, $PictArray)

EndIf

;DebugConsoleWrite(@CR)

Next

GUICtrlSetData($lab, "Scanning pass 2 for Edges")

;scan vertically

$STartScan2 = $iPa;will be used for faster line finding when I get round to it

;many points will be duplicates so use AddNewPoints function

For $aX = 1 To $iX - 1 ; for each column

$previous_pixel = False

For $aY = 1 To $iY - 1 ; for each row

$Pixel_color = PixelGetColor($aX, $aY)

;If ($Erase_White = True And $Pixel_color > 16610000) Or ($Erase_White = False And $Pixel_color < 100000) Then; almost white

If ($Erase_White = True And $Pixel_color > 0x888888) Or ($Erase_White = False And $Pixel_color <= 0x888888) Then; almost white

If $previous_pixel = False Then

$first_pixel = $aY

$previous_pixel = True

EndIf

Else ; All other colors are considered as white, this is suposed to be a black and white image!

If $previous_pixel = True Then ; OK previous was a black area

$previous_pixel = False ; reset flag

; now fill the array

; parameters

; $nLeftRect - Specifies the x-coordinate of the upper-left corner of the region in logical units.

; $nTopRect - Specifies the y-coordinate of the upper-left corner of the region in logical units.

; $nRightRect - Specifies the x-coordinate of the lower-right corner of the region in logical units.

; $nBottomRect - Specifies the y-coordinate of the lower-right corner of the region in logical units.

AddNewPoints($aX, $first_pixel, $aX, $aY - 1, $iPA, $PictArray)

EndIf

EndIf

Next

; this is needed for last pixel being white

If $previous_pixel = True Then ; OK previous was a black area

$previous_pixel = False ; reset flag

AddNewPoints($aX, $first_pixel, $aX, $aY - 1, $iPA, $PictArray)

EndIf

;DebugConsoleWrite(@CR)

Next

;GUIDelete($hGUI)

;$gui = GUICreate("outline", 600, 600, 200, 200);, -1, $WS_EX_COMPOSITED)

;GuiSwitch($gui)

DebugConsoleWrite("time started = " & _NowCalc() & @CRLF)

;$ends = $PictArray

;_ArrayDisplay($PictArray)

GUICtrlSetData($lab, "Searching points for enclosed shapes")

;Create an array of points amrking the edges of individual shapes which will used to draw the shapes

$segments = makelines($PictArray)

;_ArrayDisplay($segments)

DebugConsoleWrite("reduced no of point by " & $REducedby & @CRLF)

DebugConsoleWrite("time sfinished = " & _NowCalc() & @CRLF)

;Now draw the lines

msgbox(262144,"Start drawing","ok")

$newshape = True

$guiout = GUICreate("drawing outlines", $iX, $iY, (@DesktopWidth - $iX) / 2 + 80, (@DesktopHeight - $iY) / 2 + 80, -1, $WS_EX_TOPMOST)

$gr1 = GUICtrlCreateGraphic(0, 0, $iX, $iY)

GUICtrlSetBkColor(-1, 0xffffff)

GUICtrlSetColor(-1, 0)

GUICtrlSetGraphic(-1, $GUI_GR_COLOR, 0x00dd00)

GUISetState(@SW_SHOW, $guiout)

;Temporaily set the extended style to $WS_EX_COMPOSITED to stop the flicker

$style = GUIGetStyle($guiout)

GUISetStyle($style[0], BitOR($style[1], $WS_EX_COMPOSITED, $WS_EX_LAYERED), $guiout)

$GuiPen = GUICreate("Pencil", 77, 70, 100, 100, $WS_POPUP, $WS_EX_LAYERED)

$pic = GUICtrlCreatePic("pencil.bmp", 0, 0, 77, 76)

GUISetState()

WinSetOnTop($GuiPen, "", 1)

$wp = WinGetPos($guiout)

WinMove($GuiPen, $wp[0] + 200, $wp[1] - 40 + 100, 100)

$col = 1

$lastkx = 0

$lastky = 0

For $k = 0 To UBound($segments) - 1

If $segments[$k][0] = -99 Then ; end of line shape so start new one

$newshape = True

DebugConsoleWrite("starting new shape" & @CRLF)

Else

If $newshape Then

WinSetOnTop($GuiPen, "", 1)

$wp = WinGetPos($guiout)

$movex = $lastkx - $segments[$k][0]

$movey = $lastky - $segments[$k][1]

$maxmove = Abs($movex)

If Abs($movey) > $maxmove Then $maxmove = Abs($movey)

For $xx = 1 To $maxmove

WinMove($GuiPen, "", $wp[0] - 5 + $lastkx - $movex * $xx / $maxmove, $wp[1] - 40 + $lastky - $movey * $xx / $maxmove)

Sleep(10)

Next

GUICtrlSetGraphic($gr1, $GUI_GR_MOVE, $segments[$k][0], $segments[$k][1])

$newshape = False

Else

WinSetOnTop($GuiPen, "", 1)

$wp = WinGetPos($guiout)

WinMove($GuiPen, "", $wp[0] - 5 + $segments[$k][0], $wp[1] - 40 + $segments[$k][1])

GUICtrlSetGraphic($gr1, $GUI_GR_LINE, $segments[$k][0], $segments[$k][1])

$lastkx = $segments[$k][0]

$lastky = $segments[$k][1]

EndIf

EndIf

Sleep(10)

GUICtrlSetGraphic($gr1, $GUI_GR_REFRESH);lines added will not be shown untill the graphic is redrawn

Next

GUIDelete($GuiPen)

;trun off the $WS_EX_EXTEDED style because it stops the window caption buttons being displayed correctly

GUISetStyle($style[0], $style[1], $guiout)

While GUIGetMsg() <> -3

Sleep(10)

WEnd

;add points $x1,$y1 and $x2,$y2 if not already used

Func AddNewPoints($x1, $y1, $x2, $y2, ByRef $i, ByRef $arr)

;Grow the array if getting full

If $i >= UBound($arr) - 20 Then ReDim $arr[$i + 40][3]

;_arraydisplay($arr)

;check if the pooint already exists, if not then add it

If nopoint($x1, $y1, $i, $arr) Then

$arr[$i][0] = $x1

$arr[$i][1] = $y1

$arr[$i][2] = 0

$i += 1

EndIf

If nopoint($x2, $y2, $i, $arr) Then

$arr[$i][0] = $x2

$arr[$i][1] = $y2

$arr[$i][2] = 0

$i += 1

EndIf

EndFunc ;==>AddNewPoints

;turn the array of points into an ordered array of points so that a line can be drawn moving from one point to the next

Func makelines($points)

Local $usedpts = 0,$TotPts = UBound($points)

Dim $result[uBound($points) + 20][2]

$index = -1;element in the array $result we are building

$shapenum = 1;we are going to find the first line to draw (might end up being an enclosed shape)

$lastpoint = -1

; _ArrayDisplay($points)

Do

DebugConsoleWrite("making shape number " & $shapenum & @CRLF)

If $shapenum = 1 Then

GUICtrlSetData($lab, "Searching for an enclosed shape")

Else

GUICtrlSetData($lab, "Found " & $shapenum - 1 & " shape(s). Searching for another")

EndIf

If $lastpoint <> -1 Then

$next = $lastpoint

Else

$next = -1

findstart($next, $points);find the first unused point in $points and set $next to equal that element

EndIf

If $next > -1 Then;if a point was found

DebugConsoleWrite("$next = " & $next & "$index to use = " & $index & @CRLF)

$nowx = $points[$next][0]

$nowy = $points[$next][1]

$points[$next][2] = 1

$usedpts += 1

guictrlsetdata($Prog,100*$usedpts/$TotPts)

$index += 1

$result[$index][0] = $nowx

$result[$index][1] = $nowy

$firstx = $nowx

$firsty = $nowy

$lastpoint = -1

$startElement = $index

DebugConsoleWrite("first x,y = " & $firstx & ', ' & $firsty & '. start element = ' & $startElement & @CRLF)

Do

$closest = 999999;assume we will find something closer than this

$lastpoint = -1

;now find the closest unused point

For $p = 1 To UBound($points) - 1

If $points[$p][2] = 0 Then

$dist = (($nowx - $points[$p][0]) ^ 2) + (($nowy - $points[$p][1]) ^ 2)

If $dist < $closest Then;$dist < $toofar And

$posnear = $p

$closest = $dist

$lastpoint = $posnear

;If $dist < $toofar then $lastpoint = $posnear

DebugConsoleWrite("didt = " & $dist & @CRLF)

EndIf

;DebugConsoleWrite("didt = " & $dist & @CRLF)

EndIf

; if $closest = 1 then exitloop

Next

DebugConsoleWrite("closest = " & $closest & @CRLF)

;if the closest point found is within outr range $toofar then add it to our line

If $closest < $toofar Then

$index += 1

$result[$index][0] = $points[$posnear][0];x coord

$result[$index][1] = $points[$posnear][1];y coord

$points[$posnear][2] = 1;set it as used

$usedpts += 1

guictrlsetdata($Prog,100*$usedpts/$TotPts)

$nowx = $result[$index][0]

$nowy = $result[$index][1]

;Maybe the previous point was not needed

If $index - $startElement > 1 Then removeOnLinePoints($result, $index)

EndIf

DebugConsoleWrite("closest = " & $closest & @CRLF)

Until $closest >= $toofar

DebugConsoleWrite("last x,y = " & $result[$index][0] & ', ' & $result[$index][1] & @CRLF)

;If $lastpoint <> -1 Then

;calc distance to the start of the line

$tostart = ($firstx - $result[$index][0]) ^ 2 + ($firsty - $result[$index][1]) ^ 2

DebugConsoleWrite("to start from last = " & $tostart & @CRLF)

If $tostart < $toofar Then;we'll assume that this was an enclosed shape so we'll draw back to the start

$index += 1

ReDim $result[uBound($result) + 1][2]

$result[$index][0] = $firstx

$result[$index][1] = $firsty

EndIf

;indicate that this is the end of a line or shape

$index += 1

ReDim $result[uBound($result) + 1][2]

$result[$index][0] = -99;mark end of line

DebugConsoleWrite("element = " & $index & @CRLF)

DebugConsoleWrite("ended section with -99" & @CRLF)

Else

ExitLoop

EndIf

$shapenum += 1

Until $firstx = -1;until we can't find any more points to draw

DebugConsoleWrite("index = " & $index & @CRLF)

ReDim $result[$index + 1][2]

ConsoleWrite("total no of points is " & $index & @CRLF)

GUICtrlSetData($lab, "finishing searching for shapes")

Return $result

EndFunc ;==>makelines

Func nopoint($x, $y, $i, $ar);boolean, true if $x,$y is not included in the array $ar. $i-1 is the last element used

Local $g

For $g = 0 To $i - 1

If ($x = $ar[$g][0] And $y = $ar[$g][1]) Then Return False;the point alreday exists

Next

Return True;no such point exists yet

EndFunc ;==>nopoint

;try to reduce the number of points

Func removeOnLinePoints(ByRef $array, ByRef $i);, ByRef $lp)

Return;not wanted for pencil draqawing effect

$reduce = False

If ($array[$i - 1][1] = $array[$i - 2][1] And $array[$i - 1][1] = $array[$i][1]) Or _

($array[$i - 1][0] = $array[$i - 2][0] And $array[$i - 1][0] = $array[$i][0]) Then

$reduce = True;because we are on a straight line

Else;

If ($array[$i][1] - $array[$i - 2][1]) / ($array[$i][0] - $array[$i - 2][0]) = _

($array[$i][1] - $array[$i - 1][1]) / ($array[$i][0] - $array[$i - 1][0]) Then

$reduce = True;because on a straight line again

DebugConsoleWrite("slope reducer :" & $array[$i][1] & ', ' & $array[$i - 1][1] & ', ' & $array[$i - 2][1] & @CRLF)

DebugConsoleWrite("slope reducer :" & $array[$i][0] & ', ' & $array[$i - 1][0] & ', ' & $array[$i - 2][0] & @CRLF)

EndIf

;#ce

EndIf

If $reduce Then

$REducedby += 1

$array[$i - 1][0] = $array[$i][0]

$array[$i - 1][1] = $array[$i][1]

$i -= 1

EndIf

EndFunc ;==>removeOnLinePoints

;find the first unused point

;we should have some way of finding out if there is an open end and if so start from there

;so that the line is drawn ion one rather than two sections or more.

Func findstart(ByRef $freepoint, $arrayxy)

For $j = 0 To UBound($arrayxy) - 1

If $arrayxy[$j][2] = 0 Then;this point not used yet

$freepoint = $j

Return True

EndIf

Next

Return False

EndFunc ;==>findstart

Func DebugConsoleWrite($SDebug)

If $Debugging Then ConsoleWrite($SDebug)

EndFunc ;==>DebugConsoleWrite

Edited by martin
Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...