pC.NET

Welcome to oscc.kr



 qbasic - bmp 처리방법
2019-12-20 10:50:49
Hit : 389, Vote : 111

작성자 : 피시키드

출처 : http://www.petesqbsite.com/sections/tutorials/tuts/loading_bmps.html

Loading BMP files in QBasic

Here I will give you the general format of a .bmp image file and outline the steps needed to load and display one on the screen. Although there are many libraries that will do this for you, it's nice to write your own code and one day, you might be writing your own library =).

BMP images are actualy one of the simplest image formats as there is no compression involved.
The header is 1078 bytes long and contains vital elements such as image dimensions, colour depth and the actual palette. Following is a QBasic TYPE structure that we can use to load the image in one go:

TYPE BMPHeaderType       
        id AS STRING * 2      'Should be "BM"
        size AS LONG          'Size of the data
        rr1 AS INTEGER        '
        rr2 AS INTEGER        '
        offset AS LONG        'Position of start of pixel data
        horz AS LONG          '
        wid AS LONG           'Image width
        hei AS LONG           'Image height
        planes AS INTEGER     '
        bpp AS INTEGER        'Should read 8 for a 256 colour image
        pakbyte AS LONG       '
        imagebytes AS LONG    'Width*Height
        xres AS LONG          '
        yres AS LONG          '
        colch AS LONG         '
        ic AS LONG            '
        pal AS STRING * 1024  'Stored as <Blue, Green, Red, 0>
END TYPE


I've commented the important fields. We can use these to verify the contents of the file. Now to grab the header, all we need to do is DIM an instance of this structure, open the file and read the data. We open the file in BINARY mode so we can access the file data directly. We'll use a made-up BMP file called "demo.bmp". Here's the code:

DIM BmpHeader AS BMPHeaderType

OPEN "demo.bmp" FOR BINARY AS #1

  GET #1, , BmpHeader

' Don't close the file just yet - we're not finished!


Now we have all the data we need to load the image. From here, the rest of the file just contains the pixel data. After the GET, the file pointer is moved to the first pixel. But before we start displaying anything, we should change our current palette to the one given in our image file. The palette is stored in our header as 256 DWords (4 bytes). For each colour, 3 bytes contain the RGB palette values, while the 4th is just used for padding and is set to zero. Here's how to set the palette:


SCREEN 13					    ' Set graphics mode

a$ = BmpHeader.pal                                  ' Pal is stored in a 1024 character string

OUT &H3C8, 0					    ' Start writing from Colour 0
FOR I% = 1 TO 1024 STEP 4
        b% = ASC(MID$(a$, I%, 1)) \ 4      'blue
        g% = ASC(MID$(a$, I% + 1, 1)) \ 4  'green
        r% = ASC(MID$(a$, I% + 2, 1)) \ 4  'red
						    ' I% + 3 is set to zero.
        OUT &H3C9, r%				    ' Set the colour.
        OUT &H3C9, g%
        OUT &H3C9, b%
NEXT


Now we're ready to show something! What we do is, create two FOR .. NEXT (x and y) which extend to the dimensions of our image. Now the very weird thing here is, the image is actually stored in the file upside down! I don't know why they chose to do this, but we have to modify our Y loop to count backwards instead. Each pixel consumes exactly one byte, so this is how we read it. Unfotunately, QBasic does not have a Byte-sized (excuse the pun ;) variable. So we improvise and DIM a string of size 1, this also holds one byte. Here's the code ..


DIM Pixel AS STRING * 1                  ' Our pixel "byte".

iHeight% = BmpHeader.hei - 1             ' Subtract 1 for actual screen position
iWidth% = BmpHeader.wid - 1              '

FOR y% = iHeight% TO 0 STEP -1           ' Countdown for upsidedown image
FOR x% = 0 TO iWidth%

GET #1, , Pixel         ' read pixel     ' Read one pixel (byte)
PSET (x%, y%), ASC(Pixel)                ' Pixel is actually a string so we get the pixel 
					 ' number by requesting the "ASC" value
NEXT x%, y%

CLOSE #1


That's it! Unless your image is bigger than 320x200, you will have your BMP image on-screen.

 

Making it faster


Unless you have a really fast computer (greater than 400Mhz) you will be unsatisfied by the speed in which the image loaded. There are a couple of optimisations we can apply here.

 

  1. Intead of reading one byte at a time, read BmpHeader.wid bytes and load a line at a time
  2. We can do a memcopy from our pixel buffer to display memory instead of PSETting.


The first one is easy. We simply create a string of size BmpHeader.wid bytes. We can't do the familiar DIM statement this time, as QBasic only allows constants in that declaration. Still, we have a workaround. All we do is set a string to a specified number of SPACE$() Here's a direct replacement of the previous code:


Pixel$ = SPACE$(bmpheader.wid)

iHeight% = bmpheader.hei - 1
iWidth% = bmpheader.wid - 1

FOR y% = iHeight% TO 0 STEP -1

GET #1, , Pixel$				 ' Reads an entire line at once

FOR x% = 0 TO iWidth%
  PSET (x%, y%), ASC(MID$(Pixel$, x% + 1, 1))
NEXT x%

NEXT y%

CLOSE #1


I timed this new function against the old one and it was nearly 8 times the speed. Better eh? This should tell you about the speed of data transfer from disk =).

Now the second optimisation isn't as easy. What we do is use an Interrupt. If you don't know what this is, then search elsewhere on this site for my tutorial on it (plug, plug ;). The interrupt we'll use is the DOS interrupt (&H21) and Sub-Function 3Fh (Read from file or device). What we do is pass the interrupt a memory address (in this case, some location on the screen) and the number of bytes to read. I wont cover the code here, as it means a complete re-write. Check my tutorial on interrupts, I give an example of loading a BMP image there.
 


  피시키드
아하하하하-_-;;;
 4050
 58



69
비밀글입니다  주물럭 소스 
 피시키드
2 0 2020/09/02
68
  아두이노 코딩 
 피시키드
74 5 2020/08/22
67
비밀글입니다  모딘데코 - 회피가 주특기인 나무 업체 
 피시키드
102 14 2020/07/14
66
  USB 표면저항 값 알아내기 
 피시키드
100 19 2020/07/06
65
  커스타드 크림 제조 
 피시키드
746 109 2019/12/23
  qbasic - bmp 처리방법 
 피시키드
389 111 2019/12/20
63
  리모콘에 쓰이는 부품중 이게 뭐예요? 
 피시키드
407 114 2019/12/19
62
  buddy 3.0 정품등록 -oilman.new21.net 
 피시키드
481 116 2019/11/19
61
  아두이노 키지판 3핀 
 피시키드
448 118 2019/11/11
60
  파일리스 공격   1
 피시키드
484 122 2019/11/08
59
  자바소스 난독화 
 피시키드
576 132 2019/10/21
58
  제로보드4 파일 다운로드부분   1
 피시키드
1015 141 2019/10/15
57
  sketch for ppt 
 피시키드
6011 160 2019/10/14
56
  html 태그 (zb4, zeroboard4) 용 허용 태그 (with mysql query)  
 피시넷
1292 151 2019/10/07
55
  Windows Remote Desktop on GPU (윈도우 원격데스크톱 연결로 GPU활성화) 
 피시키드
1960 155 2019/10/01
54
비밀글입니다  통학버스 관련 카카오톡 봇 개발할것   1
 피시키드
9 0 2019/09/27
53
  MFM하드 PDF 링크 
 피시키드
614 151 2019/09/24
52
  minecraft 서버 로그 검색 
 피시키드
557 159 2019/09/22
51
  와콤 태블릿 호환표 
 피시키드
687 151 2019/09/17
50
비밀글입니다  ... 
 피시키드
4 0 2019/09/11
49
  오류코드 통합정리 php   1
 피시키드
572 159 2019/09/10
48
  lvm - lv 확장하기 
 피시키드
697 177 2019/07/31
47
  lvm #1 -- 100% 용량 전부 쓰고 싶으면 
 피시키드
691 178 2019/07/31
46
  linux boot 손상될때 
 피시키드
759 177 2019/07/31
45
비밀글입니다  정리노트-안드로이드 프로그래밍  
 피시키드
5 0 2018/10/17
44
  aa 
 피시키드
1133 280 2018/10/16
43
  파일 내부 문자열 교체 (find,perl) 
 피시키드
1645 285 2018/10/15
42
  HP 200LX 구매하고 싶습니다.   1
 Veritas
6824 448 2018/04/30
41
비밀글입니다  aps  
 피시키드
6 0 2018/03/05
40
  phpmyadmin #1698 
 피시키드
2329 482 2018/02/21

1 [2][3]



Copyright (C) 1997-2020 All Rights Reserved.