?CreateBMP("c:\4\c.txt") *================================== FUNCTION CreateBMP(sFileCoord, sFileBmp) LOCAL nf, fn, i, j, nX, nY LOCAL ARRAY aCoord[4] LOCAL sLine, nColor, iBit, nColorBit nf= FOPEN(sFileCoord) IF nf<1 WAIT WINDOW "Cannot open "+sFileCoord+" !" RETURN .F. ENDIF STORE 0 TO nX, nY DO WHILE !FEOF(nf) =ALINES(aCoord, FGETS(nf), 1, " ") nX= MAX(nX, VAL(aCoord[1]), VAL(aCoord[3])) nY= MAX(nY, VAL(aCoord[2]), VAL(aCoord[4])) ENDDO LOCAL ARRAY aMatrix[nX, nY] STORE 1 TO aMatrix =FSEEK(nf, 0, 0) DO WHILE !FEOF(nf) =ALINES(aCoord, FGETS(nf), 1, " ") FOR i=MIN(VAL(aCoord[1]), VAL(aCoord[3])) TO MAX(VAL(aCoord[1]), VAL(aCoord[3])) FOR j=MIN(VAL(aCoord[2]), VAL(aCoord[4])) TO MAX(VAL(aCoord[2]), VAL(aCoord[4])) aMatrix[i,j] = 0 ENDFOR ENDFOR ENDDO =FCLOSE(nf) *--------------------- fn= IIF(!EMPTY(sFileBmp), sFileBmp, FORCEEXT(sFileCoord,"bmp")) nf= FCREATE(fn) IF nf<1 WAIT WINDOW "Cannot create file "+fn+" !" RETURN .F. ENDIF sByte0= CreateBMPHeader(nf, 1, nX, nY) FOR j=nY TO 1 STEP -1 &&the rows in the bitmap are stored upside down. iBit= 0 nColorBit= 0 sLine= "" FOR i=1 TO nX IF iBit=8 sLine= sLine+CHR(nColorBit) iBit= 0 nColorBit= 0 ENDIF nColor= BITLSHIFT(aMatrix[i,j], 7-iBit) nColorBit= BITOR(nColorBit, nColor) iBit= iBit+1 ENDFOR =FWRITE(nf, sLine+CHR(nColorBit)+sByte0) ENDFOR =FCLOSE(nf) RETURN .T. *------------------------ FUNCTION CreateBMPHeader(nf, nBit0, nX, nY) * Creates BMP file header and returns a string * to pad each row to be adjusted to a multiple of four bytes LOCAL sLine, nByte, nByte0 LOCAL nHeadSize, nPalettesSize, nFileSize LOCAL i, nStep, nColor nByte= CEILING(nX*nBit0/8) &&meaning bytes in a row nByte0= 4*CEILING(nByte/4) &&adjust to be a multiple of four nHeadSize= 54 nPalettesSize= IIF(nBit0=24, 0, 4*2^nBit0) nFileSize= nHeadSize + nPalettesSize+ nByte0*nY sLine= "BM" &&0 sLine= sLine+CHRN(nFileSize,4) && 2 file size sLine= sLine+CHRN( 0,4) && 6 just zero (reserved) sLine= sLine+CHRN(nHeadSize+nPalettesSize,4) &&10 offset from the beginning of the file to the bitmap data sLine= sLine+CHRN(40,4) &&14 size of the BITMAPINFOHEADER structure sLine= sLine+CHRN(nX,4) &&18 width of the image, in pixels sLine= sLine+CHRN(nY,4) &&22 height of the image, in pixels sLine= sLine+CHRN( 1,2) &&26 number of planes of the target device sLine= sLine+CHRN(nBit0,2) &&28 number of bits per pixel sLine= sLine+CHRN( 0,4) &&30 type of compression sLine= sLine+CHRN( 0,4) &&34 size of the image data, in bytes. If there is no compression, it is zero sLine= sLine+CHRN( 0,4) &&38 horizontal pixels per meter on the designated targer device, usually set to zero sLine= sLine+CHRN( 0,4) &&42 vertical pixels per meter on the designated targer device, usually set to zero sLine= sLine+CHRN( 0,4) &&46 number of colors used in the bitmap, if set to zero the number of colors is calculated using the nBit0 sLine= sLine+CHRN( 0,4) &&50 number of color that are 'important' for the bitmap, if set to zero, all colors are important &&54 starts palette table =FWRITE(nf, sLine) * Note that the term palette does not refer to a RGBQUAD array, * which is called color table instead. Also note that, in a color * table (RGBQUAD), the specification for a color starts with the BLUE byte. * (In a palette a color always starts with the red byte.) * palette table sLine= "" IF nBit0#24 nStep= 255/(2^nBit0-1) nColor= 0 FOR i=1 TO 2^nBit0 sLine= sLine+REPLICATE(CHR(ROUND(nColor,0)),3)+CHR(0) nColor= nColor+nStep ENDFOR ENDIF =FWRITE(nf, sLine) RETURN REPLICATE(CHR(0),nByte0-nByte) &&to pad row *------------------------------- FUNCTION CHRN(n, ln) &&converts numeric value to binary string, &&bytes go from tail to head * n, ln - numeric value and output string length LOCAL i, s, sc s= "" sc= n FOR i=1 TO ln s= s+CHR(sc%256) sc= INT(sc/256) ENDFOR RETURN s>Koen