如何将一幅256色位图图像转换为DB格式?

huangapple go评论66阅读模式
英文:

How can I convert a 256-color bitmap image to DB format?

问题

I'm looking for a way to convert a 256-color bitmap image into an ASM file that contains inside many DB commands with a sequence of BYTES.

我正在寻找一种将256色位图图像转换为包含许多DB命令和字节序列的ASM文件的方法。

I create a bitmap with 256 colors and a resolution of 320x200 pixels.

我创建了一个具有256种颜色和320x200像素分辨率的位图。

如何将一幅256色位图图像转换为DB格式?

I would like a program that allows me to specify the Bitmap to convert. The image must be converted into an .ASM file, into a byte string in emu8086 compatible decimal or binary or hexadecimal format.

我想要一个允许我指定要转换的位图的程序。图像必须转换为.emu8086兼容的十进制、二进制或十六进制格式的字节字符串。

Then I will load the converted file (.ASM) into memory (with include command) and read every single byte by coloring the pixels on the screen.

然后,我将加载转换后的文件(.ASM)到内存中(使用include命令),并通过在屏幕上着色像素来读取每个单独的字节。

Example of generated .ASM file:

生成的.ASM文件示例:

DB 10,15,24,32,...
DB 00AH,00FH,018H,020H,...
DB 00001010B,00001111B,00010010B,00100000B,...

I try to create a program that read a .TXT file and print the content, but it did not work.

我尝试创建一个程序来读取一个.TXT文件并打印内容,但它没有起作用。

I try to build this program to convert a bitmap file in a text file with .ASM extension and a string of byte inside.

我尝试构建此程序以将位图文件转换为具有.ASM扩展名和字节字符串的文本文件。

org 100h
JMP START

INPUT DB "TEST.TXT", 0
OUTPUT DB "TEST.DB", 0
ERROR DB "FILE NOT FOUND$"

HANDLE DW ?
BUFFER DB 4 DUP(' ') ; i had found this command on internet but i don't know why i need to include it

START:

MOV AH,00H          ; set video mode
MOV AL,03H          ; 80x25 chars with 16 colors
INT 10H             ; Interrupt

; --------------------
; Read the bitmap file
; --------------------

MOV AH,3DH              ; Open the file
MOV AL,0                ; Only in read mode
MOV DX,OFFSET INPUT     ; TEST.TXT
INT 21H                 ; interrupt
JC STOP                 ; If the file not exist print an error

MOV HANDLE,AX           ; i had found this command on internet but i don't know why i need to include it

MOV BX,HANDLE
MOV DX,OFFSET BUFFER
MOV CX,0042H            ; read 42 bytes
MOV AH,3FH
INT 21H

MOV HANDLE,0000H

READ:

MOV DL,[0124H]      ; print first byte of txt file from 0124H memory location
MOV AH,02H          ; print a char on screen
INT 21H             ; Interrupt

; close the file

MOV AH,3EH
MOV BX,HANDLE
INT 21H

JMP EXIT

STOP:
MOV DX,OFFSET ERROR
MOV AH,9
INT 21H


EXIT:
ret

Thanks to all who will answer me.

感谢所有回答我的人。

英文:

I'm looking for a way to convert a 256-color bitmap image into an ASM file that contains inside many DB commands with a sequence of BYTES.

I create a bitmap with 256 colors and a resolution of 320x200 pixels.

如何将一幅256色位图图像转换为DB格式?

I would like a program that allows me to specify the Bitmap to convert. The image must be converted into an .ASM file, into a byte string in emu8086 compatible decimal or binary or hexadecimal format.
Then I will load the converted file (.ASM) into memory (with include command) and read every single byte by coloring the pixels on the screen.

Example of generated .ASM file:

DB 10,15,24,32,...
DB 00AH,00FH,018H,020H,...
DB 00001010B,00001111B,00010010B,00100000B,... 

I try to create a program that read a .TXT file and print the content, but it did not work.
I try to build this program to convert a bitmap file in a text file with .ASM extension and a string of byte inside.

org 100h
JMP START

INPUT DB "TEST.TXT", 0
OUTPUT DB "TEST.DB", 0
ERROR DB "FILE NOT FOUND$"

HANDLE DW ?
BUFFER DB 4 DUP(' ') ; i had found this command on internet but i don't know why i need to include it

START:

MOV AH,00H          ; set video mode
MOV AL,03H          ; 80x25 chars with 16 colors
INT 10H             ; Interrupt

; --------------------
; Read the bitmap file
; --------------------

MOV AH,3DH              ; Open the file
MOV AL,0                ; Only in read mode
MOV DX,OFFSET INPUT     ; TEST.TXT
INT 21H                 ; interrupt
JC STOP                 ; If the file not exist print an error

MOV HANDLE,AX           ; i had found this command on internet but i don't know why i need to include it

MOV BX,HANDLE
MOV DX,OFFSET BUFFER
MOV CX,0042H            ; read 42 bytes
MOV AH,3FH         
INT 21H


MOV HANDLE,0000H

READ:

MOV DL,[0124H]      ; print first byte of txt file from 0124H memory location
MOV AH,02H          ; print a char on screen
INT 21H             ; Interrupt

; close the file

MOV AH,3EH
MOV BX,HANDLE
INT 21H

JMP EXIT

STOP:
MOV DX,OFFSET ERROR
MOV AH,9
INT 21H


EXIT:
ret

Thanks to all who will answer me.

答案1

得分: 2

BUFFER DB 4 DUP(' ') ; 我在互联网上找到了这个命令,但我不知道为什么需要包括它

你需要它是因为你将需要使用一些内存缓冲区,你可以在其中存储(部分)作为输入使用的.BMP文件。这个特定的 db 4 dup(' ') 用法是为了保留一个小的4字节内存段,用作BUFFER(从标签名称看来)。这个值4在这里很重要,因为它限制了你可以使用这个缓冲区做什么。例如,你的程序读取了0042H字节,远远超出了缓冲区的容纳能力。缓冲区溢出会对程序产生灾难性影响!

MOV CX,0042H ; 读取42字节

希望这里有个笔误,但要知道0042H并不等于42字节,它等于66字节。

MOV HANDLE,AX ; 我在互联网上找到了这个命令,但我不知道为什么需要包括它

当打开一个文件(就像你所做的那样),DOS会返回一个文件的句柄。这是一个数字,DOS可以用它在以后的所有与该文件相关的操作中识别文件。使用一个字大小的数字要比不断通过文件名(可能包括路径)来引用文件容易得多。

MOV HANDLE,0000H
...
MOV AH,3EH
MOV BX,HANDLE
INT 21H

一旦你重置了HANDLE变量,你在CloseFile操作中就不应该再使用它了。

MOV DL,[0124H] ; 打印0124H内存位置的文本文件的第一个字节

汇编程序最清楚!使用缓冲区的名称并写成:mov dl, BUFFER。在emu8086中使用方括号是可选的。

英文:

> BUFFER DB 4 DUP(' ') ; i had found this command on internet but i don't know why i need to include it

You need it because you will want to use some memory buffer where you can store (part of) the .BMP file that you use as input.
What this particular db 4 dup(' ') does is reserving a small 4-byte portion of memory to serve as a BUFFER (from looking at the label name). That value 4 is important here because it limits what you can do with this buffer. eg. Your program reads 0042H bytes which is much more than the buffer can accommodate. The buffer overflows and the effect on the program will be disastrous!

> MOV CX,0042H ; read 42 bytes

Hoping for a typo here, but do know that 0042H is not the same as 42 bytes. It is 66 bytes.

> MOV HANDLE,AX ; i had found this command on internet but i don't know why i need to include it

When opening a file (like you did), DOS gives back a handle for the opened file. This is a number by which DOS can identify the file in all the subsequent interactions that you plan to undertake concerning this file. Working with a word-sized number is much easier than continually having to refer to the file via its name (which could include a path as well).

> MOV HANDLE,0000H
> ...
> MOV AH,3EH
> MOV BX,HANDLE
> INT 21H

Once you've reset the HANDLE variable, you should no longer be using it in the CloseFile operation.

> MOV DL,[0124H] ; print first byte of txt file from 0124H memory location

The assembler knows best! Use the name for the buffer and write: mov dl, BUFFER. The square brackets are optional when using emu8086.


I wrote a demo that converts a 320x200 256-color .BMP file into a .TXT file filled with db lines. This is a good starting point for what you ultimately need. It's just a starting point because:

  • you need to prompt the user to provide the filename(s)
  • you need to include suitable error messages
  • you need to not skip the file headers but rather parse them, so you can:
    • verify whether the .BMP file is a valid bitmap file
    • support a bitmap with dimensions other than 320 x 200
    • support a bitmap with an alternative orientation
  • you need to not skip the color table but rather use it, so you can show the picture as it was intended, color-wise

The program was tested on a true MS-DOS machine. It ran blazingly fast, but I'm not sure about how fast/slow emu8086 can run this.

	ORG 	256

	mov 	dx, OFFSET TxtF
	xor 	cx, cx
	mov 	ah, 3Ch		; DOS.CreateFile
	int 	21h	    	; -> AX CF
	jc  	Exit
	mov 	TxtH, ax

	mov 	dx, OFFSET BmpF
	mov 	ax, 3D00h	; DOS.OpenFile
	int 	21h	    	; -> AX CF
	jc  	Exit
	mov 	BmpH, ax

	mov 	dx, 14+40+1024	; Skip .BMP headers and color table
	xor 	cx, cx
	mov 	bx, ax
	mov 	ax, 4200h	; DOS.SeekFile
	int 	21h 		; -> DX:AX CF
	jc  	Exit

	mov 	bp, (320*200)/16
OuterLoop:
	mov 	dx, OFFSET BmpS
	mov 	cx, 16
	mov 	bx, BmpH
	mov 	ah, 3Fh		; DOS.ReadFile
	int 	21h 		; -> AX CF
	jc  	Exit
	cmp 	ax, cx
	jne 	Exit

	mov 	di, OFFSET TxtS+3
	mov 	si, OFFSET BmpS
InnerLoop:
	lodsb
	aam 	100
	add 	ah, '0'
	mov 	[di], ah
	aam
	add 	ax, '00'
	xchg	al, ah
	mov 	[di+1], ax
	add 	di, 4
	loop	InnerLoop

	mov 	dx, OFFSET TxtS
	mov 	cx, 68
	mov 	bx, TxtH
	mov 	ah, 40h		; DOS.WriteFile
	int 	21h 		; -> AX CF
	jc  	Exit

	dec 	bp
	jnz 	OuterLoop

	mov 	bx, BmpH
	mov 	ah, 3Eh		; DOS.CloseFile
	int 	21h 		; -> AX CF

	mov 	bx, TxtH
	mov 	ah, 3Eh		; DOS.CloseFile
	int 	21h 		; -> AX CF

Exit:
	mov 	ax, 4C00h	; DOS.Terminate
	int 	21h
; ------------------------------
	ALIGN	2
BmpS	db	16 dup 0
TxtS	db	'db ???', 15 dup (',???'), 13, 10
BmpH	dw	0
TxtH	dw	0
BmpF	db	'EXAMPO4.BMP', 0	; 65078 bytes
TxtF	db	'EXAMPO4.TXT', 0	; 272000 bytes

What my output looked like:

> db 000,003,000,017,000,000,000,000,000,000,000,012,151,177,113,087
> db 125,151,151,151,140,151,175,158,183,189,245,246,216,244,224,226
> db 165,164,148,132,125,087,062,076,115,103,069,066,048,158,097,001
> db 059,000,091,091,005,012,000,000,000,011,029,106,024,005,048,062
> db 224,212,204,212,183,189,062,214,184,196,160,237,125,162,180,190
> db 000,003,000,017,000,000,000,000,000,000,000,012,151,177,113,087
> db 125,151,151,151,140,151,175,158,183,189,245,246,216,244,224,226
> db 165,164,148,132,125,087,062,076,115,103,069,066,048,158,097,001
> db 059,000,091,091,005,012,000,000,000,011,029,106,024,005,048,062
> db 224,212,204,212,183,189,062,214,184,196,160,237,125,162,180,190
> --- 3990 more lines ---

huangapple
  • 本文由 发表于 2023年6月9日 00:06:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/76433792.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定