|
Post by Walt Decker on Nov 12, 2022 9:35:35 GMT -5
That is interesting. I deliberately put a glitch in the dll to find out if anyone would actually test it and ask if the output is correct. The output was not correct, but it is now.
The .png is actually 1000 x 1032 so the number of tiles will not produce an aggregate area that size. There are 5 choices:
1) do no adjustments and either leave part of the right side and bottom out of the area 2) adjust the number of tiles so that part of the right end and bottom is filled 3) adjust the tile size to fit the source area 4) wrap the left side and top to the right and bottom 5) adjust the source to fit the target
Which would you prefer? I chose option 5
|
|
|
Post by Rod on Nov 12, 2022 13:32:47 GMT -5
Doh! We need to get this forum back on track with plain, vanilla, native BASIC solutions.
We don’t need traps and pitfalls, we need simple working solutions that beginners and new to Liberty coders can understand.
So we all need to spend more time coding native Liberty solutions, including myself.
The less API we see going forwards the better. iMHO.
|
|
|
Post by Rod on Nov 18, 2022 7:07:20 GMT -5
Ok it turns out to be "relatively" straightforward to do all of this working with the .bmp file. The benefits of working with the file are that it is fast and there is very little memory use as the bulk of the data stays out on file. I adopted a very simple approach to decide how to segment the bmp. I simply get the integer value of the number of segments and so leave a few edge pixels behind. Other strategies could be adopted.
You will benefit from reading a little about .bmp file format. It consists of a simple 14 byte file header, followed by a 40 byte image header that defines width height bit level etc. Only the width height and file sizes need changed in the header.
The one main quirk is that a raster line that consists of a series of BGR values must be saved as a multiple of four bytes, so there can be some padding bytes at the end of the rasterline. The padding for the input bmp can be different from the output bmp depending on the number of pixels.
A bmp is also stored upside down, the top visible line is actually stored last in the file. That could be fixed but it segments the bmp nonetheless.
If this code needs tweaked, or bug fixes just ask. I have hard coded the output file name and path, change that to what you desire.
[segment] 'decide how we are going to segment the image '4x3 split giving 12 sub bmp files xseg=4 yseg=3
filedialog "Open 24 bit bmp file", "*.bmp", fileName$ if fileName$ <>"" then cursor hourglass open fileName$ for input as #bmp 'input the file and bmp header info info$ = Input$(#bmp,54) biBitCount=value(mid$(info$,29,2)) 'bits per pixel bfOffBits=value(mid$(info$,11,4)) 'picture data offset in file biWidth=value(mid$(info$,19,4)) 'bmp pixel width biHeight=value(mid$(info$,23,4)) 'bmp pixel height biSize=value(mid$(info$,15,4)) 'bmp header size 40 close #bmp
'work out start of picture data and how to move through file impos=bfOffBits+1
'work out input files padding, each raster line must be a 4byte multiple m=3*biWidth/4 '3 bytes per pixel for 24bit biPadding = 4*(1-(m-int(m))) mod 4
'what size is a raster line including padding? biRaster=3*biWidth+biPadding
'what width and height will each sub segment be? 'we will simply take the integer value of the division so dropping 'the last few pixels at the edge of the image siWidth=int(biWidth/xseg) siHeight=int(biHeight/yseg)
'work out sub files padding, each raster line must be a 4byte multiple m=3*siWidth/4 '3 bytes per pixel for 24bit siPadding = 4*(1-(m-int(m))) mod 4 for n= 1 to siPadding siPadding$=siPadding$+chr$(0) print len(siPadding$) next
'what size is the sub image raster line excluding padding siRaster=3*siWidth
'work out sub file's actual file size including padding siSize=54+(3*siWidth+siPadding)*siHeight
'now create the new file header for the sub bmps
'bmpfileheader size=siSize b4=int(size/(256*256*256)) size=size-b4*256*256*256 b3=int(size/(256*256)) size=size-b3*256*256 b2=int((size)/256) b1=size-b2*256 buffer$="BM"+chr$(b1)+chr$(b2)+chr$(b3)+chr$(b4) buffer$=buffer$+chr$(0)+chr$(0)+chr$(0)+chr$(0) buffer$=buffer$+chr$(54)+chr$(0)+chr$(0)+chr$(0) 'bmpheader buffer$=buffer$+chr$(40)+chr$(0)+chr$(0)+chr$(0) size=siWidth b4=int(size/(256*256*256)) size=size-b4*256*256*256 b3=int(size/(256*256)) size=size-b3*256*256 b2=int((size)/256) b1=size-b2*256 buffer$=buffer$+chr$(b1)+chr$(b2)+chr$(b3)+chr$(b4) size=siHeight b4=int(size/(256*256*256)) size=size-b4*256*256*256 b3=int(size/(256*256)) size=size-b3*256*256 b2=int((size)/256) b1=size-b2*256 buffer$=buffer$+chr$(b1)+chr$(b2)+chr$(b3)+chr$(b4) buffer$=buffer$+chr$(1)+chr$(0)+chr$(24)+chr$(0) buffer$=buffer$+chr$(0)+chr$(0)+chr$(0)+chr$(0) size=siSize-54 b4=int(size/(256*256*256)) size=size-b4*256*256*256 b3=int(size/(256*256)) size=size-b3*256*256 b2=int((size)/256) b1=size-b2*256 buffer$=buffer$+chr$(b1)+chr$(b2)+chr$(b3)+chr$(b4) buffer$=buffer$+chr$(19)+chr$(11)+chr$(0)+chr$(0) buffer$=buffer$+chr$(19)+chr$(11)+chr$(0)+chr$(0) buffer$=buffer$+chr$(0)+chr$(0)+chr$(0)+chr$(0) buffer$=buffer$+chr$(0)+chr$(0)+chr$(0)+chr$(0)
'open the original image as binary keeping it out on file open fileName$ for binary as #bmp
for y=0 to yseg-1 for x=0 to xseg-1 'now save away the sub images sfileName$="d:/temp/subimage"+right$("00"+str$(x),2)+right$("00"+str$(y),2)+".bmp" open sfileName$ for output as #subbmp #subbmp buffer$; for yy=0 to siHeight-1 seek #bmp, ipos+(y*siHeight+yy)*biRaster+(x*siRaster) raster$=input$(#bmp,siRaster) #subbmp raster$+siPadding$; next close #subbmp next next close #bmp cursor normal end if
wait
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))*65536) value=value+(asc(mid$(x$,4,1))*4294967296) end select end function
|
|
|
Post by Rod on Nov 18, 2022 8:06:31 GMT -5
If you are experimenting this little routine will break down the header you have created for your bmp.
' a bmp header is 54 bytes long 14 for the file header ' and 40 for the bmp info. If it is less then 24bit ' color it will have a color table. ' a 256 color file has 256 4 byte colors in a table ' following the headers ' Liberty BASIC and Just BASIC save in the screen ' resolution of your system so you will likely get ' 32bit or 24bit bmps, they also add three color ' quads or triplets so the actual pixel data does ' not start at 55 it starts 12 or 9 bytes later ' looking at bfOffBits will tell you. filedialog "Open bmp file", "*.bmp", fileName$ open fileName$ for input as #bmp 'the bmpfileheader bmp$ = Input$(#bmp,lof(#bmp)) print "bfType =";mid$(bmp$,1,2) 'always BM print "bfSize =";value(mid$(bmp$,3,4)) print "bfReserved =";value(mid$(bmp$,7,2)) print "bfReserved =";value(mid$(bmp$,9,2)) print "bfOffBits =";value(mid$(bmp$,11,4)) ' the bitmapinfoheader print "biSize =";value(mid$(bmp$,15,4)) print "biWidth =";value(mid$(bmp$,19,4)) print "biHight =";value(mid$(bmp$,23,4)) print "biPlanes =";value(mid$(bmp$,27,2)) print "biBitCount =";value(mid$(bmp$,29,2)) print "biCompress =";value(mid$(bmp$,31,4)) print "biSizeImage =";value(mid$(bmp$,35,4)) print "biXPels =";value(mid$(bmp$,39,4)) print "biYPels =";value(mid$(bmp$,43,4)) print "biClrUsed =";value(mid$(bmp$,47,4)) print "biClrImport =";value(mid$(bmp$,51,4))
if value(mid$(bmp$,29,2)) = 32 then pos=value(mid$(bmp$,11,4))+1 for col=1 to 24 print "Byte ";pos,"Pixel ";str$(col);","; print asc(mid$(bmp$,pos,1));","; print asc(mid$(bmp$,pos+1,1));","; print asc(mid$(bmp$,pos+2,1));","; print asc(mid$(bmp$,pos+3,1)) pos=pos+4 next col end if if value(mid$(bmp$,29,2)) = 24 then pos=value(mid$(bmp$,11,4))+1 for col=1 to 24 print "Byte ";pos,"Pixel ";str$(col);","; print asc(mid$(bmp$,pos,1));","; print asc(mid$(bmp$,pos+1,1));","; print asc(mid$(bmp$,pos+2,1)) pos=pos+3 next col end if wait
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 3 value=asc(mid$(x$,1,1)) value=value+(asc(mid$(x$,2,1))*256) value=value+(asc(mid$(x$,3,1))*65536) case 4 value=asc(mid$(x$,1,1)) value=value+(asc(mid$(x$,2,1))*256) value=value+(asc(mid$(x$,3,1))*65536) value=value+(asc(mid$(x$,4,1))*16777216) end select
end function
|
|
|
Post by Walt Decker on Nov 18, 2022 9:26:25 GMT -5
Well, that is fine provided the format is MSBMP. What if the format is JPG, PNG, TIFF or a host of others? Personally, I am lazy so I will use other tools rather than taking the time to research each different format or loading each image into a paint app and translating to BMP before rendering with LB.
|
|