 |

06-28-2002, 07:15 AM
|
|
|
About writing a file
|
Hello.
I have a PictureBox (PLMask) with black background and I draw white and filled circels on it.
When I save it as a BMP it is almost 1,4 MB heavy because it is 800x600 pixels wide.
So I thought I made my own file as I only need 2 colors.
Here is the code:
Code:
Dim Color As Long
Dim CountX As Integer
Dim CountY As Integer
Open "c:\temp\MSKtest.msk" For Output As #1
CountX = -1
While CountX < 800
CountX = CountX + 1
CountY = -1
While CountY < 600
CountY = CountY + 1
Color = GetPixel(Form1.PLMask.hdc, CountX, CountY)
If Color = 16777215 Then Print #1, "1" Else Print #1, "0"
Wend
Wend
Close #1
Now funny enough the file has almost the same size as the BMP
and looks like this:
0
0
1
0
and so on, you get the idea. I happen to know that a file looking like this:
0,0,1,0
would be much smaller, but I don't know how to do that.
Also I was wondering if there isn't any way to save it as some kind of binary-file as only 0 and 1 are used (I know that in fact any computer-file is binary). I mean, that when I would open the file in a texteditor I would not see the 0's and 1's but some mess of cryptic signs, I am sure you have allready seen what I mean.
Thanks for reading this!
|
Last edited by B_old; 06-28-2002 at 07:28 AM.
|

06-28-2002, 07:19 AM
|
 |
Lost Soul
Super Moderator * Guru *
|
|
Join Date: May 2001
Location: Vorlon
Posts: 18,885
|
|
|
For every pixel ON/OFF you use a complete byte.
A byte is made of 8 bits so you could store 8 bits (ON/OFF) in a byte, making your file 8 times smaller.
|
|

06-28-2002, 07:23 AM
|
|
|
Ohhh
|
That sounds indeed intresting.
Could you tell me how to save 8 ON/OFF's in on byte?
|
|

06-28-2002, 07:30 AM
|
 |
Lost Soul
Super Moderator * Guru *
|
|
Join Date: May 2001
Location: Vorlon
Posts: 18,885
|
|
The most simple way is something like this (untested)
Code:
Dim bByte As Byte
Dim CountX As Long, CountY As Long, lBit As Long
Dim Color As Long
Open "c:\temp\MSKtest.msk" For Binary As #1
For CountY = 0 To 599
For CountX = 0 To 799 Step 8
' Missing line
bByte = 0
For lBit = 0 To 7
Color = GetPixel(Form1.PLMask.hdc, CountX + lBit, CountY)
bByte = bByte + Color * (2 ^ lBit)
Next lBit
Put #1, , bByte
Next CountX
Next CountY
Close #1
|
Last edited by Flyguy; 06-28-2002 at 04:15 PM.
|

06-28-2002, 07:32 AM
|
 |
Hell's Angel
Retired Moderator * Guru *
|
|
Join Date: Jul 2001
Location: Yorkshire, UK
Posts: 10,394
|
|
|
Think about the binary representation of numbers:
00001000 = &H8
So you can set the fourth bit by:
btPixels = btPixels Or &H8
and you clear it by:
btPixels = btPixels And (Not &H8)
|
__________________
A wise one man once said "what you talking about dog breath"
|

06-28-2002, 07:39 AM
|
|
|
Aha
|
well, your code did not exactly work.
It said something about overflow.
And also if I don't understand Banjo's explanation yet, your two codes will give me something to think about.
Thank you!
|
|

06-28-2002, 11:16 AM
|
 |
Code Meister
Retired Moderator * Guru *
|
|
Join Date: Aug 2000
Location: Vancouver, BC, Canada
Posts: 10,441
|
|
800 pixels across eh....that means 100 bytes. So you could code it like:
Code:
Dim x as integer, y as integer, b as byte, dest as integer
dim dc as long
dc = Form1.PLMask.hdc
dest = freefile
open ""c:\temp\MSKtest.msk"" for binary as #dest
For y = 0 to 599
for x = 0 to 799 step 8
b = 0
if GetPixel(dc,x,y) then b = b or 1 'set first bit
if getpixel(dc,x+1,y) then b = b or 2 'set 2nd bit
if getpixel(dc, x+2,y) then b = b or 4 'set 3rd bit
if getpixel(dc,x+3,y) then b= b or 8 'set 4th bit
if getpixel(dc,x+4,y) then b = b or 16 'set 5th bit
if getpixel(dc, x+5,y) then b=b or 32 'set 6th bit
if getpixel(dc,x+6,y) then b=b or 64 'set 7th bit
if getpixel(dc,x+7,y) then b=b or 128 'set 8th bit
put #dest,,b
next x
next y
close #dest
Reading it would be similar...
Code:
Dim x as integer, y as integer, b as byte, src as integer
dim dc as long
dc = Form1.PLMask.hdc
src = freefile
open ""c:\temp\MSKtest.msk"" for binary as #src
For y = 0 to 599
for x = 0 to 799 step 8
get #src,,b
if b AND 1 then SetPixel(dc,x,y,&HFFFFFF)
if b AND 2 then SetPixel(dc,x+1,y,&HFFFFFF)
if b AND 4 then SetPixel(dc,x+2,y,&HFFFFFF)
if b AND 8 then SetPixel(dc,x+3,y,&HFFFFFF)
if b AND 16 then SetPixel(dc,x+4,y,&HFFFFFF)
if b AND 32 then SetPixel(dc,x+5,y,&HFFFFFF)
if b AND 64 then SetPixel(dc,x+6,y,&HFFFFFF)
if b AND 128 then SetPixel(dc,x+7,y,&HFFFFFF)
next x
next y
close #src
|
__________________
"I have a plan so cunning you could put a tail on it and call it a weasel!" - Edmund Blackadder
|

06-28-2002, 01:04 PM
|
|
|
WOW
|
Cool. BillSoo, your code is a nice example, thanks.
The file is 60 Bytes light.
There is just on thing. When I read the file again there are yellow (!) stripes in between.
I wonder if that has to do with
Declare Function SetPixelV& Lib "gdi32" (ByVal hdc&, ByVal x&, ByVal y&, ByVal crColor&)
which is supposed to be 8 times faster then SetPixel (which does not really work in your sample anyway).
Also it would be really nice if you could explain to me why it has to be 'b = b or 1' or 'b and 1'.
Moreover I wonder if it is smart to use the Binary mode for normal words to.
Anyway, thanks for the great help!
|
|

06-28-2002, 02:35 PM
|
 |
Code Meister
Retired Moderator * Guru *
|
|
Join Date: Aug 2000
Location: Vancouver, BC, Canada
Posts: 10,441
|
|
|
Binary mode can be used for plain text, but in some circumstances, you may run into problems with unicode conversions. Where binary really excels is when you have records (ie. user defined types). You can have an array of records and just read or write the whole array to/from the file with just one line. Random mode also works for this, and is the usual way one works with records, but I prefer binary because I can also attach a header to my file.
I don't use SetPixelV myself so I can't comment on it. Why do you say SetPixel doesn't work.
Also, why do you say the file is 60bytes light? Is it not 60,000 bytes in size?
The AND and OR operators are used to do bitwise operations.
To set the 1st bit, we can say
00000000 OR 00000001
Because 0 OR 1 = 1
Similarily, to set the 4th bit, we can say
00000000 OR 00001000
If 'b' already contains a value, the OR operator won't mess it up...
01010101 OR 00100000 = 01110101
The AND is similar.
01101010 AND 1 is 0 (false)
01101010 AND 2 is 2 (non zero is true)
|
__________________
"I have a plan so cunning you could put a tail on it and call it a weasel!" - Edmund Blackadder
|

06-28-2002, 04:16 PM
|
 |
Lost Soul
Super Moderator * Guru *
|
|
Join Date: May 2001
Location: Vorlon
Posts: 18,885
|
|
I forgot the reset bByte everytime.
Complete code:
Code:
Dim bByte As Byte
Dim CountX As Long, CountY As Long, lBit As Long
Dim Color As Long
Open "c:\temp\MSKtest.msk" For Binary As #1
For CountY = 0 To 599
For CountX = 0 To 799 Step 8
' Missing line
bByte = 0
For lBit = 0 To 7
Color = GetPixel(Form1.PLMask.hdc, CountX + lBit, CountY)
bByte = bByte + Color * (2 ^ lBit)
Next lBit
Put #1, , bByte
Next CountX
Next CountY
Close #1
|
|

06-29-2002, 10:46 AM
|
|
|
OK
|
To ArnoutV:
It says that there is a overflow in bBbyte.
to BillSoo:
SetPixel worked not for me, I think there was something wrong the syntax. Of course it is 60,000 bytes, I just err... don't know, sorry.
Thanks for the explanation, I maybe will be able to use it sometime!
Thank you all for the help by the way.
|
|

06-29-2002, 11:16 AM
|
 |
Lost Soul
Super Moderator * Guru *
|
|
Join Date: May 2001
Location: Vorlon
Posts: 18,885
|
|
Forgot to include the color check ...
Code:
Dim bByte As Byte
Dim CountX As Long, CountY As Long, lBit As Long
Dim Color As Long
Open "c:\temp\MSKtest.msk" For Binary As #1
For CountY = 0 To 599
For CountX = 0 To 799 Step 8
' Missing line
bByte = 0
For lBit = 0 To 7
Color = GetPixel(Form1.PLMask.hdc, CountX + lBit, CountY)
' Forgot checking Color
If Color = 16777215 Then
bByte = bByte + (2 ^ lBit)
End If
Next lBit
Put #1, , bByte
Next CountX
Next CountY
Close #1
|
|

06-29-2002, 11:43 AM
|
|
|
|
Yeah. No it works!
And it can even be read with BillSoo's reading code.
But still there appear this strange yellow stripes.
|
|

07-12-2002, 02:08 PM
|
|
|
Hello!
I had another look on this thing as I surely will use it.
Anyway this yellow stripes must not appear.
As I still not truly unterstand the code posted by you, I cannot tell wether the writing or the reading is wrong.
Anyway I figured out that the stripes (the go from top to bottom)
are 1 pixel wide. The first one appears on the 3 pixel of the X-coordinate and then every 8 pixels there is another.
Therefore I wrote this code:
Code:
Dim CountX As Integer
Dim CountY As Integer
Dim Color As Long
CountX = 3
While CountX < 800
CountX = CountX + 8
CountY = 0
While CountY < 600
CountY = CountY + 1
Color = GetPixel(Form1.PLMask.hdc, CountX, CountY)
If Color = 1114111 Then SetPixelV dc, CountX, CountY, &HFFFFFF
Wend
Wend
This code finds the yellow stripes and makes them white (as I know that they only appear every 8 pixels I don't need to search every X-pixel for yellow color and that is faster of course)
Still it would be even faster if the yellow stripes did not appear in the first hand, therefore I wonder if you cóuld have another look on your code to help me.
Anyway I appreciate your great help so far!!
Thank you.
|
|
|
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
|
|
|
| Thread Tools |
|
|
| Display Modes |
Linear Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
|
|
|