This adapts my bit-map pixel routines so you can choose any type of bitmap image & from it create a series of instructions to an x-raster on a drum driven as y so a pen or extruder head can deposit ( or not) at each location. By calling an installed copy of ImageMagick it can load virtually any type of image file. LB can only display directly a BMP file, and by doing the conversiion I get the easy ability to read pixels directly from the BMP file, which is a loss-less raster file of the image. Think of a target machine like an old dot-matrix printer with only one pin available. Twenty years ago I used this technique to draw high-res paper graphs of temperature & sun strength- A3 width and twenty feet per month!
For this project ( from a query on the forums) it is to be envisaged as 'writing' onto a roll of paper or fabric. In LB you move to an x,y coordinate and set a pixel. On the intended machine you move to the point and emit a 'blob'!
The intention would be to create valid G-code for a machine that accepted it- but most of my machines I drive directly to the steppers & servos. The version below finishes with a massive file in the clipboard, ready to paste into an editor and save. Equally easy to automate that step. In my case I'd be sending commands directly via a USB 'serial' EiBotBoard driver to steppers & servos.
The image is scaled for you to width of 720 pixels, based on fabric width of 48 inches at 15 dpi, and roll length of the same- but easily changed. If the image is not square, it will have an empty border on one side. The image is displayed on-screen, and essentially raster scanned, although this is done for greater speed by reading the pixels direct from the saved BMP file. If a pixel brightness exceeds a threshold it sends a black or white pixel to over-write the original image, and to generate the instruction file. Strictly you should use a weighted mean of R, G and B, but I would normally pre-process the image anyway in GIMP or similar.
You need Liberty BASIC and ImageMagick to have been installed first.
' **************************************************
' **** skeleton3b August 2013 tenochtitlanuk ****
' **************************************************
' ** Requires installation of ImageMagick from **
' ** http://www.imagemagick.org/script/index.php **
' Thanks to Rod and Anatoly ( tsh73) especially for
' get-pixel routines and examples.
nomainwin
graphicbox #w.gb, 3, 2, 720, 720
texteditor #w.te, 730, 2, 200, 720
WindowWidth =950
WindowHeight =780
open "Show image" for window as #w
#w "trapclose quit"
#w.gb "down ; fill 100 100 100 ; flush"
#w.te "G90"
#w.te "; absolute coordinate positioning"
[openpic]
filedialog "Open image for processing", "*.bmp; *.gif; *.jpg", fname$
if fname$ ="" then goto [openpic]
f$ =mid$( fname$, 2+len( DefaultDir$))
f$ =word$( f$, 1, ".")
file$ ="convert -sample 720x720 "; chr$(34); fname$; chr$( 34); " "; f$; "720x720.bmp"
run "cmd.exe /k "; chr$( 34); file$; chr$( 34), HIDE
timer 5000, [carryon] ' allow 5 secs for image to be converted
wait
[carryon]
timer 0
loadbmp "image", f$ +"720x720.bmp"
#w.gb "drawbmp image 0 0"
#w.gb "flush"
unloadbmp "image"
dim r( 1, 1), g( 1, 1), b( 1, 1)
global bmpOffset, bmpColDepth, rasterWidth, BisOpen, GisOpen
BisOpen =0: GisOpen =0
call readBMPData f$ +"720x720.bmp"
wait
sub quit h$
#w.te "!copy" ' copy potential g-code file to clipboard ( or could save it)
close #h$
if BisOpen =1 then close #bmp
if GisOpen =1 then close #gbd
end
end sub
sub GetBmpDimensions fileName$, byref width, byref height
temp$ =input$( #gbd, 24)
close #gbd
GisOpen =0
width =asc( mid$( temp$, 19, 1)) +asc( mid$( temp$, 20, 1)) *256
height =asc( mid$( temp$, 23, 1)) +asc( mid$( temp$, 24, 1)) *256
end sub
sub readBMPData fileName$ 'reads into arrays r g b (w,h)
open fileName$ for input as #gbd
GisOpen =1
open fileName$ for binary as #bmp
BisOpen =1
lenFile =lof( #bmp)
info$ =input$( #bmp, 54) 'get bmp info
bmpWidth = value( mid$( info$, 19, 2)) 'extract bmp info -width in pixels of image
bmpHeight = value( mid$( info$, 23, 2)) ' height in pixels of image
bmpOffset = value( mid$( info$, 11, 4)) 'offset in file to pixel data 54 or 66 for Liberty bmps
bpp = value( mid$( info$, 29, 2)) 'color depth, 32bit /4bytes or 24bit /3bytes
bmpColDepth = bpp /8
rasterWidth =bmpWidth *bmpColDepth 'work out padding, a raster must end on a 4 byte boundary
p =rasterWidth mod 4
if p then rasterWidth =rasterWidth +( 4 -p)
'print "Bitmap "; fileName$; " "; bmpWidth; " x "; bmpHeight; " "; bpp; " bpp"
seek #bmp, bmpOffset 'set pointer to first of color quad or triplet info
if bpp <>24 and bpp <>32 then 'we'll accept only 24 or 32 bpp images so pixels will be RGB or RGB0
print "bpp value is "; bpp
print "Come on! JB generated bitmap supposed to be 24 or 32 bpp"
print "* Refuse to continue! *"
end
end if
'dimension array. Clears it too
dim r( bmpWidth +1, bmpHeight +1), g( bmpWidth +1, bmpHeight +1), b( bmpWidth +1, bmpHeight +1)
'print "Reading to array ... "; 'read the data
c =0
for y = 0 to bmpHeight -1
aLine$ =input$( #bmp, rasterWidth)
scan
for x =0 to bmpWidth -1
pixel$ =mid$( aLine$, x *bmpColDepth +1, bmpColDepth)
'and y is reversed
re =asc( mid$( pixel$, 3, 1)): r( x, bmpHeight -1 -y) =re ' fill array with each pixel's RGB
gr =asc( mid$( pixel$, 2, 1)): g( x, bmpHeight -1 -y) =gr
bl =asc( mid$( pixel$, 1, 1)): b( x, bmpHeight -1 -y) =bl
'#w.gb "color "; bl; " "; gr; " "; re ' colour-swapped false colours.
grey =int( ( re +gr +bl) /3)
if grey >140 then grey =255 else grey =0 ' threshold for black/white
#w.gb "color "; grey; " "; grey; " "; grey
#w.gb "set "; x; " "; bmpHeight -y
#w.te "G00 X"; x; " Y"; y
if grey >140 then #w.te "G=code for pendown/up"
next
next
close #bmp
BisOpen =0
print "Done."
end sub
function value( x$)
select case len( x$)
case 1
value = asc( x$)
case 2
value =asc( mid$( x$,1,1))
value =value +( asc( mid$( x$, 2, 1)) *256)
case 4
value =asc( mid$( x$, 1, 1))
value =value+( asc( mid$( x$, 2, 1)) *256)
value =value+( asc( mid$( x$, 3, 1)) *256^2)
value =value+( asc( mid$( x$, 4, 1)) *256^3)
end select
end function