ernie
New Member
Posts: 44
|
Post by ernie on Jan 1, 2021 22:54:46 GMT -5
I need to have small grayscale graphics created in LB converted to binary for placement in an RTF file. Is there a way to save an image created in LB as a binary file? If not, does anyone know of a command line converter of BMP to binary?
Ernie
|
|
|
Post by Rod on Jan 2, 2021 4:16:19 GMT -5
My understanding of RTF is Rich Text File and I am not sure how such a file uses binary images. Binary itself implies 1010101010 but in fact images are always stored as bytes. So you have a grayscale image on view in a Liberty BASIC graphicbox and you want to embed that in a RTF? Does the RTF need the header that always accompanies a .bmp or is it just the image data bytes you need?
A little more info will help.
|
|
|
Post by tsh73 on Jan 2, 2021 4:20:31 GMT -5
What exactly is "binary"? Why don't just insert BMP in RTF (I dunno, open RTF in Word Pad, paste with Ctrl-C?) ?
|
|
|
Post by Rod on Jan 2, 2021 4:23:41 GMT -5
I see the RTF community discusses binary images, needs more investigation on our part. will be back
|
|
|
Post by Rod on Jan 2, 2021 4:36:11 GMT -5
Well it would seem binary is possible but not the preferred option. In fact there are a raft of options for including images in a RTF. I think binary is the wrong approach. BMP data is allowed. You can easily create a bmp with BMPSAVE command and there must surely be RTF examples of importing .bmp files to RTF documents?
|
|
ernie
New Member
Posts: 44
|
Post by ernie on Jan 2, 2021 5:32:23 GMT -5
Rod you are right, it does look more like text. LB creates an RTF for the user and also the BMP meant for insertion into the RTF.
When I open the BMP with Wordpad and save as an .RTF file, the beginning of the file looks like the characters below
I need the (text?) equivalent of the BMP for insertion into the RTF. The image is a single small, 4 bit, 32k, 625 x 102 pixels grayscale file. It is a custom bar chart that changes depending upon user input. I need a command-line way to do this that can be distributed with software and invisible to the user.
Any ideas or leads would be greatly appreciated. Thank you.
Ernie
{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1033{\fonttbl{\f0\fnil\fcharset0 Calibri;}} {\*\generator Riched20 10.0.19041}\viewkind4\uc1 \pard\sa200\sl240\slmult1\f0\fs22\lang9{\pict{\*\picprop}\wmetafile8\picw16536\pich2699\picwgoal8640\pichgoal1410 0100090000035e3f00000000353f000000000400000003010800050000000b0200000000050000 000c0266007102030000001e0004000000070104000400000007010400353f0000410b2000cc00 660071020000000066007102000000002800000071020000660000000100040000000000000000 000000000000000000000000000000000000000000ffffff00e6e6e60064646400bfbfbf000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000111111111111111111111111111111111111111111111111111111111111111111111111 111111111111111111111111111111111111111111111111111111111111111111111111111111 1111111111111111111111
|
|
|
Post by Rod on Jan 2, 2021 6:05:13 GMT -5
Ahhh, a few more questions.
You are writing a program in Liberty BASIC that outputs a rtf file for end user display?
If you are drawing the chart in Liberty it will not be 4bit it will be the bit depth of your display (it will look grayscale), probably 24bit. So where is the chart/bmp coming from?
If you load a bmp into word and save as rtf it saves it as a metafile so don't know how that helps us.
It is relatively easy to extract image data from a .bmp file and put it in the RTF file. BUT, that requires we know what we are doing with the RTF language, it requires tags and preamble which I unfortunately know nothing of.
But to get the best help please clarify that you are creating a RTF with Liberty code and that you wish to include bmp data, clarify where the .bmp comes from. Other readers will have RTF knowlege.
|
|
ernie
New Member
Posts: 44
|
Post by ernie on Jan 2, 2021 7:45:59 GMT -5
Thanks, Rod.
Yes, I am writing a program in Liberty Basic that creates an RTF file for the user.
This program also draws a grayscale chart on screen and uses getbmp and bmpsave to create the 24-bit grayscale BMP on disk.
I need to (using command line) to extract the BMP image data for placement inside the RTF. The RTF code I can figure out. I just need help with the extraction of BMP data.
I'm not loading the BMP into word or any other word processor--the code above from Wordpad was offered to illustrate the kind of output needed.
This has turned out to be a real head-scratcher.
|
|
|
Post by Rod on Jan 2, 2021 9:28:55 GMT -5
I am not sure why we need the command line, Liberty BASIC is perfectly capable of opening the .bmp extracting the info and saving it to the RTF file. use BMPSAVE to save your image as a .bmp then run this code and copy and paste back the results.
If it is a Liberty BASIC generated .bmp I expect to see the image data offset start at 66. We just need to open the .bmp and read in those bytes.
Now if you had the image what RTF code would you wrap round those bytes? Also does RTF make any mention of what header info is needed?
' 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 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))
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
|
|
ernie
New Member
Posts: 44
|
Post by ernie on Jan 2, 2021 11:05:17 GMT -5
I am creating Liberty Basic software for distribution. This software takes data entered by the user and creates an RTF file that is the end product and purpose of the software. This much works well. I would like to add an image to the RTF file, a bar chart that illustrates some of the numbers contained within the RTF document. Liberty Basic creates this image and saves it as a BMP. The image changes depending upon the user’s input. This process needs to be command-line so as to be transparent and keep manufacture of the document automated and requiring no post-production work from the user of adding or maintaining image files separate from their document). Adding an image to an RTF file requires more than metadata. RTF files, like some web pages (e.g. bluegriffon.org/), natively store entire images as text (converted from image files) within the RTF or HTML code. You can see this is the case with RTF by (in Windows) placing an image into a WordPad file and save it to disk. Open the file with notepad and you will see some "wrapper" code above and below that envelopes the image. The LB-produced image that I am working with, for example, when run through WordPad begins with: {\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1033{\fonttbl{\f0\fnil\fcharset0 Calibri;}} {\*\generator Riched20 10.0.19041}\viewkind4\uc1 \pard\sa200\sl240\slmult1\f0\fs22\lang9{\pict{\*\picprop}\wmetafile8\picw16536\pich2699\picwgoal8640\pichgoal1410 and ends with: }\par \pard\sa200\sl276\slmult1\par } The above RTF code does not change even when LB creates the same graphic with different values and it, too is run through WordPad, saved as an RTF and examined from Notepad. This means I already have the RTF code needed for this project. What I am lacking is the image converted to text. Between the starting and ending code above is the bitmap image converted to text, the first few lines (the entire image is 832 lines) look like this: 0100090000035e3f00000000353f000000000400000003010800050000000b0200000000050000 000c0266007102030000001e0004000000070104000400000007010400353f0000410b2000cc00 660071020000000066007102000000002800000071020000660000000100040000000000000000 000000000000000000000000000000000000000000ffffff00e6e6e60064646400bfbfbf000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000111111111111111111111111111111111111111111111111111111111111111111111111 111111111111111111111111111111111111111111111111111111111111111111111111111111 1111111111111111111111 My questions are: Does LB have a way to save it's image data in this format, as an alternative to saving the image as a BMP? Is there some way that LB can convert a BMP file to this text format? Does anybody reading this know of a command-line option for converting BMP files to this text?
|
|
|
Post by tenochtitlanuk on Jan 2, 2021 11:15:05 GMT -5
I wonder if RTF is the way to go? You do ask for suggestions... Wikipedia says.. [i]RTF is a proprietary document file format with published specification developed by Microsoft Corporation from 1987 until 2008 for cross-platform document interchange with Microsoft products.[/i] If the aim is for users to PRINT output including greyscale graphics and perhaps test, that's easy directly from LB. If you want to create a document that can be saved and passed on, PDF is a much better way IMHO. The code following will print text +graphics, OR if you have printing to PDF as default will create a saved document that can be worked on by almost any word processor... The code below prints a page of text/graphics. See nomainwin
WindowWidth = 950 WindowHeight =1080
open "Peano curve RC" for graphics_nsb as #wg
#wg "trapclose quit"
loadbmp "scr", "Peano4b.bmp" 'replace with your BMP or add code to draw your bar chart etc... #wg "down ; drawbmp scr 50 20"
#wg "up ; goto 40 800 ; font 18" #wg "\" +"Yes, I am writing a program in Liberty Basic" +chr$( 13) +_ " that creates an RTF file for the user." +chr$( 13) +_ "This program also draws a grayscale chart on screen" +chr$( 13) +_ "Why not export as PDF instead??"
#wg "flush ; print 950"
wait
sub quit h$ close #wg end end sub
|
|
ernie
New Member
Posts: 44
|
Post by ernie on Jan 2, 2021 11:39:27 GMT -5
tenochtitlanuk - PDF is a great suggestion but unfortunately in this instance the users will be editing and adding to the document so it needs to be a word processing document.
|
|
|
Post by Rod on Jan 2, 2021 12:53:32 GMT -5
So we have a chunk of "text" embeded in a RTF which we want to replace, the surrounding wrapper does not change. So all we need to do is understand the "text" format which is in fact the image data. Now the wrapper states "wmetadat8" which would appear to be a 256 color image. So passing it through wordpad has converted the 24bit .bmp into a metadata image chunk. So a little more complex that reading a .bmp
All is not lost. But in the example I researched there was a color table towards the beginning of the wrapper. But if it is grayscale perhaps it is not needed. Or is there a color table at the start?
What we need is a real .bmp and a real .rtf both from the same image. Then we can see if conversion is possible. As with all these things programmers stick to kiss so it may simply be a series of single bytes defining each pixel. You are presenting the bytes to us as hexdec values. how big is the image how many hex codes define the image (00-FF). does that match the image width/height?
Can you post a .bmp and the RTF data of that image?
|
|
|
Post by tsh73 on Jan 2, 2021 14:14:24 GMT -5
I've read a bit into it - and it looks like it is Windows object normally got by some API call By look of it, it could be even BMP (as objclass Paint.Picture) I tried to put BMP file and looked on source file and RTF - it is same file(binary data) + some heading I figured out some of the heading Saved from WordPad, bitmap has 2 likely doubling parts {\object\objemb{\*\objclass Paint.Picture}\objw150\objh75{\*\objdata with some header and HEX codes for BMP file and right after that {\result{\pict\wmetafile8\picw150\pich75\picwgoal150\pichgoal75 with some more binary code. wmetafile8 is Windows Metafile with embedded BMP. As I've read, normal way is to call Win API to get EMF from BMP, then get WMF from EMF, then save it as stream This stream likely goes here Now, I have no idea about WMF part, so I cut it off It is clearly a hack but it kind of works in Win XP and Win 7 Resulting file: * opens if Win XP WordPad * opens in C# richTextBox * errors on Word, Open Office * after resaving from WordPad, "grows" WMF part and starts open in Word and Open Office no problem. EDIT ** after resaving from C# richTextBox with richTextBox1.SaveFile(), "grows" WMF part and starts open in Word and Open Office no problem. So I made a program that does this. And it works in Win XP * (will check in Win7) EDIT **yes it does work the same on Win 7 But testing in Win10 shows that Microsoft broke (of at least changed) WordPad on Windows 10 Here I see "some contents are blocked" warning - and no file contents. On files fixed by resaving from WordPad/ C# richTextBox, it gives warning but shows contents. This likely be recent thing, see for example answers.microsoft.com/en-us/windows/forum/all/wordpad-some-contents-are-blocked-message-if-an/d46f6b4f-6222-41af-8083-3b2600a6b8d9and forums.malwarebytes.com/topic/259359-wordpad-ms-word-security-warning-on-images/But RTF I got still opens in richtextbox in c# exe. Have a look. 'crude bmp2rtf attempt ' needs JB2 for decHex 'putting whole BMP file as objclass Paint.Picture 'WARNING 'tested in Win XP MS Office 2007 OpenOffice 4.1 (all things are OLD) 'it does open in WordPad 'it does open in C# 2008 (all things are OLD) 'RichTextBox with richTextBox1.LoadFile 'but it DOES NOT opens in Word 2007 and OpenOffice 4.1 '(but if you resave if from Word pad, it grows \wmetafile8 part ant starts to open both ways) ' 'alas does not work on Win10 - says "some contents are blocked"
print "1) First draw the bitmap" open "making bitmap" for graphics_nsb_nf as #gr #gr "home; down" #gr "posxy cx cy" 'center screen gives us half width, height #gr "trapclose [quit]" x0=30 y0=250 N=10
#gr "place ";x0;" ";y0 #gr "go 230" #gr "place ";x0;" "; y0 #gr "turn 90; go 300" #gr "place ";x0+90;" ";y0+30 #gr "\Bitmap example"
h = 250/N for i = 0 to N-1 x = x0+i*h #gr "place ";x;" "; y0 #gr "boxfilled ";x+h;" "; y0-rnd(0)*200 next
print "2) Now get the bitmap"
bmpW=2*cx-1 '-1 just for a case bmpH=2*cy-1 #gr "getbmp pic 0 0 ";bmpW;" "; bmpH bmpName$="bmp2embed.bmp" bmpSave "pic", bmpName$ print "saved ";bmpW;"x";bmpH;" 32-bit bitmap" print bmpName$
close #gr
print "3) Now recode bitmap to binary" print "(would take a while)"
outFName$ = "bmp2embed.bin" open bmpName$ for input as #1 fSize = lof(#1) close #1 print "BMP file size is ";fSize print "Processing..." locate 5, 9 print "0";"%" 'goto [skipRecode]
open bmpName$ for input as #1 open outFName$ for output as #2 t0=time$("ms") ll=1 while not(eof(#1)) a$=input$(#1,1) 'aa$=lower$(right$("0"+dechex$(asc(a$)),2)) aa$=right$("0"+dechex$(asc(a$)),2) #2 aa$; ll=ll+1 if ll>78/2 then ll=1 #2 "" scan t1=time$("ms") if t1-t0>200 then t0=t1 locate 5, 9 print using("###", 100*loc(#1)/fSize);"%" end if end if wend 'print dechex$(lof(#1)) close #2 close #1 [skipRecode] print "... done" print "Bin file written as" print outFName$
print "4) Now assemble RTF file" rtfFName$ = "rtfWithBMP.rtf" open rtfFName$ for output as #3
'using file created by WordPad on WinXP 'feel free to add your own preamble CRLF$=chr$(13)+chr$(10)
RTFpreamble$=_ "{\rtf1\ansi\ansicpg1251\deff0\deflang1049{\fonttbl{\f0\fswiss\fcharset0 Arial;}{\f1\fswiss\fcharset204{\*\fname Arial;}Arial CYR;}}"+CRLF$+_ "{\*\generator Msftedit 5.41.15.1515;}\viewkind4\uc1\pard\lang1033\f0\fs20 " #3 RTFpreamble$; RTFBeforeText$="Hello there" 'anything you want to add before bitmap #3 RTFBeforeText$; 'now, bitmap after a newline (\par) 'I understand only bitmap width, height and file size 'anything else is black magic s1=fSize mod 256 s2=int(fSize/256) mod 256 s3=int(fSize/256^2) mod 256 s4=int(fSize/256^3)
embeddedBMPHeader$=_ "\par"+CRLF$+_ "{\object\objemb{\*\objclass Paint.Picture}"+CRLF$+_ "\objw"+str$(bmpW*15)+CRLF$+_ "\objh"+str$(bmpH*15)+CRLF$+_ "{\*\objdata"+CRLF$+_ "01050000"+CRLF$+_ "02000000"+CRLF$+_ "07000000"+CRLF$+_ "50427275736800"+CRLF$+_ "00000000"+CRLF$+_ "00000000"+CRLF$+_ right$("0"+dechex$(s1),2)+right$("0"+dechex$(s2),2)+_ right$("0"+dechex$(s3),2)+right$("0"+dechex$(s4),2) 'last is BMP file size in HEX lower bytes first
#3 embeddedBMPHeader$
print "... adding BIN file ..." open outFName$ for input as #4 embeddedBMPdata$ = input$(#4, lof(#4)) close #4 #3 embeddedBMPdata$
'I see first two lines part of the \objdata but I have no idea OBJDataEnding$=_ "01050000"+CRLF$+_ "00000000"+CRLF$+_ "}" 'end of \objdata #3 OBJDataEnding$
RTFending$="\par"+CRLF$+_ "Any text you would add in the end"+CRLF$+_ "\lang1049\f1\par"+CRLF$+_ "}" #3 RTFending$ close #3
'rtfFName$ = "rtf01.rtf" print "RTF file written as" print rtfFName$
print "5) Now try to open RTF file (likely with WordPad)" 'run "explorer.exe "; rtfFName$ run "write "; rtfFName$ 'opens WordPad with Win XP print "Hopefilly that's all" print "If wordPad is not opened, try open file "; rtfFName$;" manually" print "Now re-read comments at top of this file"
wait
[quit] close #gr end
|
|
|
Post by tenochtitlanuk on Jan 2, 2021 15:53:39 GMT -5
Ernie- can you post the whole section from the RTF that represents the image, and tell us its width and height? The data seems saved as pure ASCII, so it takes two bytes to specify a bit value that can go over 127 thru' 255. eg '89504e470' seems to mean x89, x 50, etc.. or am I wildly off course? When I saved a RTF with a 10x10 bmp embedded it seemed to take 418 bytes?
|
|