Go Back  Xtreme Visual Basic Talk > Legacy Visual Basic (VB 4/5/6) > General > About writing a file


Reply
 
Thread Tools Display Modes
  #1  
Old 06-28-2002, 07:15 AM
B_old
Guest
 
Posts: n/a
Default 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.
Reply With Quote
  #2  
Old 06-28-2002, 07:19 AM
Flyguy's Avatar
Flyguy Flyguy is offline
Lost Soul

Super Moderator
* Guru *
 
Join Date: May 2001
Location: Vorlon
Posts: 18,885
Default

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.
Reply With Quote
  #3  
Old 06-28-2002, 07:23 AM
B_old
Guest
 
Posts: n/a
Default Ohhh

That sounds indeed intresting.
Could you tell me how to save 8 ON/OFF's in on byte?
Reply With Quote
  #4  
Old 06-28-2002, 07:30 AM
Flyguy's Avatar
Flyguy Flyguy is offline
Lost Soul

Super Moderator
* Guru *
 
Join Date: May 2001
Location: Vorlon
Posts: 18,885
Default

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.
Reply With Quote
  #5  
Old 06-28-2002, 07:32 AM
Banjo's Avatar
Banjo Banjo is offline
Hell's Angel

Retired Moderator
* Guru *
 
Join Date: Jul 2001
Location: Yorkshire, UK
Posts: 10,394
Post

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"
Reply With Quote
  #6  
Old 06-28-2002, 07:39 AM
B_old
Guest
 
Posts: n/a
Default 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!
Reply With Quote
  #7  
Old 06-28-2002, 11:16 AM
BillSoo's Avatar
BillSoo BillSoo is offline
Code Meister

Retired Moderator
* Guru *
 
Join Date: Aug 2000
Location: Vancouver, BC, Canada
Posts: 10,441
Default

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
Reply With Quote
  #8  
Old 06-28-2002, 01:04 PM
B_old
Guest
 
Posts: n/a
Default 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!
Reply With Quote
  #9  
Old 06-28-2002, 02:35 PM
BillSoo's Avatar
BillSoo BillSoo is offline
Code Meister

Retired Moderator
* Guru *
 
Join Date: Aug 2000
Location: Vancouver, BC, Canada
Posts: 10,441
Default

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
Reply With Quote
  #10  
Old 06-28-2002, 04:16 PM
Flyguy's Avatar
Flyguy Flyguy is offline
Lost Soul

Super Moderator
* Guru *
 
Join Date: May 2001
Location: Vorlon
Posts: 18,885
Default

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
Reply With Quote
  #11  
Old 06-29-2002, 10:46 AM
B_old
Guest
 
Posts: n/a
Default 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.
Reply With Quote
  #12  
Old 06-29-2002, 11:16 AM
Flyguy's Avatar
Flyguy Flyguy is offline
Lost Soul

Super Moderator
* Guru *
 
Join Date: May 2001
Location: Vorlon
Posts: 18,885
Default

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
Reply With Quote
  #13  
Old 06-29-2002, 11:43 AM
B_old
Guest
 
Posts: n/a
Default

Yeah. No it works!
And it can even be read with BillSoo's reading code.
But still there appear this strange yellow stripes.
Reply With Quote
  #14  
Old 07-12-2002, 02:08 PM
B_old
Guest
 
Posts: n/a
Default 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.
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump

Advertisement:





Free Publications
The ASP.NET 2.0 Anthology
101 Essential Tips, Tricks & Hacks - Free 156 Page Preview. Learn the most practical features and best approaches for ASP.NET.
subscribe
Programmers Heaven C# School Book -Free 338 Page eBook
The Programmers Heaven C# School book covers the .NET framework and the C# language.
subscribe
Build Your Own ASP.NET 3.5 Web Site Using C# & VB, 3rd Edition - Free 219 Page Preview!
This comprehensive step-by-step guide will help get your database-driven ASP.NET web site up and running in no time..
subscribe
 
 
-->