1
1
Fork 0
mirror of https://github.com/QB64-Phoenix-Edition/QB64pe.git synced 2024-07-03 12:21:20 +00:00
QB64-PE/internal/help/Creating_Icon_Bitmaps.txt
2021-01-24 00:36:34 -03:00

476 lines
24 KiB
Plaintext

==Icon Viewer and Bitmap Creator==
The following program can be used to view Icon or Cursor images and save them as Bitmaps. When you answer Y the bitmap is saved with a black background so that it can be PUT using [[XOR]] on to the [[AND]] image. The AND image will be black and white if the image is irregularly shaped(not a full box image). It is placed first using [[PUT (graphics statement)|PUT]] with the AND action or can be placed using [[_PUTIMAGE]] with the color white [[_ALPHA]] being set to 0. In that case, try just placing the XOR image with the color black 0 [[_ALPHA|alpha]] with [[_SETALPHA]].
{{small|Code by Ted Weissgerber}}
{{TextStart}}
'' ''
'********************************* IconType.BI INCLUDE FILE ********************************
{{Cb|TYPE}} IconType 'Icon or cursor file header
Reserved {{Cb|AS}} {{Cb|INTEGER}} 'Reserved (always 0)
ID {{Cb|AS}} {{Cb|INTEGER}} 'Resource ID (Icon = 1, Cursor = 2)
Count {{Cb|AS}} {{Cb|INTEGER}} 'Number of icon bitmaps in Directory of icon entries array
{{Cb|END}} {{Cb|TYPE}} '6 bytes
{{Cb|TYPE}} ICONENTRY 'or unanimated Cursor entry (see ANI for animated cursors)
PWidth {{Cb|AS}} {{Cb|_BYTE}} 'Width of icon in pixels (USE THIS)
PDepth {{Cb|AS}} {{Cb|_BYTE}} 'Height of icon in pixels (USE THIS)
NumColors {{Cb|AS}} {{Cb|_BYTE}} 'Maximum number of colors: (2 or 16 colors. 256 or 24/32 bit = 0}
RES2 {{Cb|AS}} {{Cb|_BYTE}} 'Reserved. Not used (always 0)
HotSpotX {{Cb|AS}} {{Cb|INTEGER}} 'Icon: NumberPlanes(normally 0), Cursor: hotspot pixels from left
HotSpotY {{Cb|AS}} {{Cb|INTEGER}} 'Icon: BitsPerPixel(normally 0), Cursor: hotspot pixels from top
DataSize {{Cb|AS}} {{Cb|LONG}} 'Length of icon bitmap in bytes (USE THIS)
DataOffset {{Cb|AS}} {{Cb|LONG}} 'Offset byte position of icon bitmap data header in file(add 1)
{{Cb|END}} {{Cb|TYPE}} '16 bytes
{{Cb|TYPE}} ICONHEADER 'Bitmap type header found using entry DataOffset + 1
IconHSize {{Cb|AS}} {{Cb|LONG}} 'size of ICON header (always 40 bytes)
ICONWidth {{Cb|AS}} {{Cb|LONG}} 'bitmap width in pixels. (width and double height may be missing)
ICONDepth {{Cb|AS}} {{Cb|LONG}} 'Total map height in pixels (TWO TIMES the image height).
NumPlanes {{Cb|AS}} {{Cb|INTEGER}} 'number of color planes. Must be set to 1.
BPP {{Cb|AS}} {{Cb|INTEGER}} 'bits per pixel 1, 4, 8, 16, 24 or 32.(USE THIS for BPP)
Compress {{Cb|AS}} {{Cb|LONG}} 'compression method should always be 0.
RAWSize {{Cb|AS}} {{Cb|LONG}} 'size of the raw ICON image data(may only be {{Cb|XOR}} mask size).
Hres {{Cb|AS}} {{Cb|LONG}} 'horizontal resolution of the image(not normally used)
Vres {{Cb|AS}} {{Cb|LONG}} 'vertical resolution of the image(not normally used)
NumColors {{Cb|AS}} {{Cb|LONG}} 'number of colors in the color palette(not normally used)
SigColors {{Cb|AS}} {{Cb|LONG}} 'number of important colors used(not normally used)
{{Cb|END}} {{Cb|TYPE}} '40 byte
'' ''
{{TextEnd}}
{{CodeStart}}
'' ''
{{Cl|REM}} {{Cl|$INCLUDE}}: 'IconType.BI'
{{Cl|DEFINT}} A-Z
{{Cl|DIM}} Icon {{Cl|AS}} IconType
{{Cl|DIM}} {{Cl|SHARED}} Item, BPP
{{Cl|DIM}} {{Cl|SHARED}} wide&, deep&, bmp&, bmpStretch&
{{Cl|DIM}} Image(26000)
dst& = {{Cl|_NEWIMAGE}}(800, 600, 32)
{{Cl|SCREEN (statement)|SCREEN}} dst&
hdr$ = " & File ID = # ## Image(s) in file #######, bytes "
ico$ = " Size = ## X ## Colors = ## Planes = # BPP = ## "
cur$ = " Size = ## X ## Colors = ## HotSpot X = ## Y = ## "
dat$ = " DATA Size = #####, bytes {{Cl|DATA}} Offset = ######, "
bm1$ = " HeaderSize = ## MaskArea = ## X ## Planes = # BPP = ## "
bm2$ = " Compression = # RAW Data Size = ######, bytes "
{{Cl|LOCATE}} 20, 20: {{Cl|LINE INPUT}} "Enter an ICOn or CURsor file name: ", IconName$
L = {{Cl|LEN}}(IconName$)
{{Cl|IF}} L = 0 {{Cl|THEN}} {{Cl|SOUND}} 400, 4: {{Cl|SYSTEM}}
dot = {{Cl|INSTR}}(IconName$, ".")
{{Cl|IF}} dot = 0 {{Cl|THEN}}
Save$ = IconName$: IconName$ = IconName$ + ".ICO"
{{Cl|ELSE}} Save$ = {{Cl|LEFT$}}(IconName$, dot - 1)
{{Cl|END IF}}
{{Cl|OPEN}} IconName$ {{Cl|FOR (file statement)|FOR}} {{Cl|BINARY}} {{Cl|AS}} #1
length& = {{Cl|LOF}}(1)
{{Cl|PRINT}}
{{Cl|IF}} length& {{Cl|THEN}}
{{Cl|GET}} #1, 1, Icon
{{Cl|SELECT CASE}} Icon.ID
{{Cl|CASE}} 1: IC$ = "Icon": ent$ = ico$
{{Cl|CASE}} 2: IC$ = "Cursor": ent$ = cur$
{{Cl|CASE ELSE}}: IC$ = "Bitmap?"
{{Cl|END SELECT}}
{{Cl|LOCATE}} 22, 20: {{Cl|PRINT USING}} hdr$; IC$; Icon.ID; Icon.Count; length&
{{Cl|IF}} Icon.Count {{Cl|THEN}}
count = Icon.Count
{{Cl|DIM}} {{Cl|SHARED}} Entry(count) {{Cl|AS}} ICONENTRY
{{Cl|DIM}} {{Cl|SHARED}} Header(count) {{Cl|AS}} ICONHEADER
{{Cl|FOR...NEXT|FOR}} Item = 1 {{Cl|TO}} count '16 bytes each entry
{{Cl|GET}} #1, , Entry(Item)
{{Cl|NEXT}}
{{Cl|VIEW PRINT}} 24 {{Cl|TO}} 32
{{Cl|FOR...NEXT|FOR}} Item = 1 {{Cl|TO}} count
{{Cl|GET}} #1, Entry(Item).DataOffset + 1, Header(Item) 'ADD 1 to offsets!
{{Cl|COLOR}} {{Cl|_RGB}}(255, 255, 0): {{Cl|LOCATE}} 24, 30
{{Cl|IF}} count > 1 {{Cl|THEN}} {{Cl|PRINT}} " IMAGE ENTRY #"; Item {{Cl|ELSE}} {{Cl|PRINT}} " IMAGE ENTRY"
{{Cl|COLOR}} {{Cl|_RGB}}(50, 200, 255)
{{Cl|PRINT USING}} ent$; Entry(Item).PWidth; Entry(Item).PDepth; Entry(Item).NumColors; Entry(Item).HotSpotX; Entry(Item).HotSpotY
{{Cl|PRINT USING}} dat$; Entry(Item).DataSize; Entry(Item).DataOffset
{{Cl|PRINT USING}} bm1$; Header(Item).IconHSize; Header(Item).ICONWidth; Header(Item).ICONDepth, Header(Item).NumPlanes; Header(Item).BPP
{{Cl|PRINT USING}} bm2$; Header(Item).Compress; Header(Item).RAWSize
{{Cl|PRINT}}
k$ = {{Cl|INPUT$}}(1) 'Palette(4 or 8BPP) and/or {{Cl|XOR (boolean)|XOR}} mask starts immediately after an ICONHEADER
wide& = Entry(Item).PWidth: deep& = Entry(Item).PDepth: BPP = Header(Item).BPP
{{Cl|IF}} BPP > 8 {{Cl|THEN}} BitColor = 32 {{Cl|ELSE}} BitColor = 256 'assign for proper colors
bmpStretch& = {{Cl|_NEWIMAGE}}(4 * wide&, 4 * deep&, BitColor) 'set either 256 or 32
bmp& = {{Cl|_NEWIMAGE}}(wide&, deep&, BitColor) 'don't bother with {{Cl|_FREEIMAGE}}, reuse them!
{{Cl|SELECT CASE}} BPP
{{Cl|CASE}} 1: OneBit
{{Cl|CASE}} 4: FourBIT
{{Cl|CASE}} 8: EightBIT
{{Cl|CASE}} {{Cl|IS}} > 8: True{{Cl|COLOR}}
{{Cl|END SELECT}}
{{Cl|IF}} BPP < 24 {{Cl|THEN}} {{Cl|_COPYPALETTE}} bmp&, bmpStretch&
{{Cl|_PUTIMAGE}} , bmp&, bmpStretch&
{{Cl|_DEST}} 0: {{Cl|_PUTIMAGE}} (100, 0), bmpStretch&
{{Cl|SOUND}} 600, 3
{{Cl|COLOR}} {{Cl|_RGB}}(255, 0, 255): {{Cl|LOCATE}} {{Cl|CSRLIN}}, 30: {{Cl|PRINT}} "Save as Bitmap? (Y/N)";
k$ = {{Cl|INPUT$}}(1)
k$ = {{Cl|UCASE$}}(k$)
{{Cl|PRINT}} k$ + {{Cl|SPACE$}}(1);
{{Cl|IF}} k$ = "Y" {{Cl|THEN}}
SaveFile$ = Save$ + {{Cl|LTRIM$}}({{Cl|STR$}}(Item)) + ".BMP"
ThirtyTwoBit 0, 0, wide& - 1, deep& - 1, bmp&, SaveFile$
{{Cl|END IF}}
{{Cl|IF}} k$ = "Y" {{Cl|THEN}} {{Cl|PRINT}} "Saved!" {{Cl|ELSE}} {{Cl|PRINT}} "Not saved"
{{Cl|AND (boolean)|AND}}Mask
{{Cl|IF}} BPP < 24 {{Cl|THEN}} {{Cl|_COPYPALETTE}} bmp&, bmpStretch&
{{Cl|_PUTIMAGE}} , bmp&, bmpStretch&
{{Cl|_DEST}} 0: {{Cl|_PUTIMAGE}} (400, 0), bmpStretch&
{{Cl|IF}} k$ = "Y" {{Cl|THEN}}
ANDFile$ = Save$ + {{Cl|LTRIM$}}({{Cl|STR$}}(Item)) + "BG.BMP"
ThirtyTwoBit 0, 0, wide& - 1, deep& - 1, bmp&, ANDFile$
{{Cl|END IF}}
k$ = {{Cl|INPUT$}}(1)
{{Cl|CLS}}
{{Cl|NEXT}}
{{Cl|VIEW PRINT}}
{{Cl|ELSE}} {{Cl|SOUND}} 400, 4: {{Cl|CLOSE}} #1: {{Cl|PRINT}} "No images entries found!": {{Cl|END}}
{{Cl|END IF}}
{{Cl|ELSE}}: {{Cl|CLOSE}} #1: {{Cl|SOUND}} 400, 4: {{Cl|KILL}} IconName$: {{Cl|END}}
{{Cl|END IF}}
{{Cl|CLOSE}} #1
{{Cl|END}}
{{Cl|SUB}} OneBit 'adapted from TheBob's Winbit 'B & W monochrome images ONLY (NO {{Cl|PALETTE}} data)
BitsOver = wide& {{Cl|MOD}} 32
{{Cl|IF}} BitsOver {{Cl|THEN}} ZeroPAD$ = {{Cl|SPACE$}}((32 - BitsOver) \ 8)
{{Cl|_DEST}} bmp&
y = deep& - 1: p$ = " "
{{Cl|DO}}
x = 0
{{Cl|DO}}
{{Cl|GET}} #1, , p$
Byte{{Cl|VAL}} = {{Cl|ASC}}(p$)
{{Cl|FOR...NEXT|FOR}} Bit% = 7 {{Cl|TO}} 0 {{Cl|STEP}} -1 'read bits left to right
{{Cl|IF}} Byte{{Cl|VAL}} {{Cl|AND}} 2 ^ Bit% {{Cl|THEN}} {{Cl|PSET}} (x, y), 15 {{Cl|ELSE}} {{Cl|PSET}} (x, y), 0
x = x + 1
{{Cl|NEXT}} Bit%
{{Cl|LOOP}} {{Cl|WHILE}} x < wide&
{{Cl|GET}} #1, , ZeroPAD$ ' 'prevents odd width image skewing
y = y - 1 '
{{Cl|LOOP}} {{Cl|UNTIL}} y = -1
{{Cl|END SUB}}
{{Cl|SUB}} EightBIT 'adapted from TheBob's Winbit '256 palette data Colors (8 BPP)
{{Cl|IF}} wide& {{Cl|MOD}} 4 {{Cl|THEN}} ZeroPAD$ = {{Cl|SPACE$}}(4 - (wide& {{Cl|MOD}} 4))
{{Cl|_DEST}} bmp&
a$ = " ": u$ = " "
{{Cl|OUT}} {{Cl|&H}}3C8, 0
{{Cl|FOR...NEXT|FOR}} Colr = 0 {{Cl|TO}} 255
{{Cl|GET}} #1, , a$: Blu = {{Cl|ASC}}(a$) \ 4
{{Cl|GET}} #1, , a$: Grn = {{Cl|ASC}}(a$) \ 4
{{Cl|GET}} #1, , a$: Red = {{Cl|ASC}}(a$) \ 4
{{Cl|OUT}} {{Cl|&H}}3C9, Red
{{Cl|OUT}} {{Cl|&H}}3C9, Grn
{{Cl|OUT}} {{Cl|&H}}3C9, Blu
{{Cl|GET}} #1, , u$ '--- unused byte
{{Cl|NEXT}} Colr
y = deep& - 1: p$ = " "
{{Cl|DO}}: x = 0
{{Cl|DO}}
{{Cl|GET}} #1, , p$
{{Cl|PSET}} (x, y), {{Cl|ASC}}(p$)
x = x + 1
{{Cl|LOOP}} {{Cl|WHILE}} x < wide&
{{Cl|GET}} #1, , ZeroPAD$ ' 'prevents odd width image skewing
y = y - 1
{{Cl|LOOP}} {{Cl|UNTIL}} y = -1
{{Cl|END SUB}}
{{Cl|SUB}} FourBIT 'adapted from TheBob's Winbit '16 palette data colors (4 BPP = 8 or 16 color)
{{Cl|_DEST}} bmp&
{{Cl|IF}} wide& {{Cl|MOD}} 8 {{Cl|THEN}} ZeroPAD$ = {{Cl|SPACE$}}((8 - wide& {{Cl|MOD}} 8) \ 2) 'prevents odd width image skewing
a$ = " ": u$ = " "
{{Cl|FOR...NEXT|FOR}} Colr = 0 {{Cl|TO}} 15
{{Cl|OUT}} {{Cl|&H}}3C8, Colr
{{Cl|GET}} #1, , a$: Blu = {{Cl|ASC}}(a$) \ 4
{{Cl|GET}} #1, , a$: Grn = {{Cl|ASC}}(a$) \ 4
{{Cl|GET}} #1, , a$: Red = {{Cl|ASC}}(a$) \ 4
{{Cl|OUT}} {{Cl|&H}}3C9, Red
{{Cl|OUT}} {{Cl|&H}}3C9, Grn
{{Cl|OUT}} {{Cl|&H}}3C9, Blu
{{Cl|GET}} #1, , u$ '--- unused byte
{{Cl|NEXT}} Colr
y = deep& - 1: p$ = " "
{{Cl|DO}}
x = 0
{{Cl|DO}}
{{Cl|GET}} #1, , p$
HiNIBBLE = {{Cl|ASC}}(p$) \ {{Cl|&H}}10
LoNIBBLE = {{Cl|ASC}}(p$) {{Cl|AND (boolean)|AND}} {{Cl|&H}}F
{{Cl|PSET}} (x, y), HiNIBBLE
x = x + 1
{{Cl|PSET}} (x, y), LoNIBBLE
x = x + 1
{{Cl|LOOP}} {{Cl|WHILE}} x < wide&
{{Cl|GET}} #1, , ZeroPAD$ ' 'prevents odd width image skewing
y = y - 1
{{Cl|LOOP}} {{Cl|UNTIL}} y = -1
{{Cl|END SUB}}
{{Cl|SUB}} ANDMask ' '{{Cl|AND (boolean)|AND}} MASK is B & W. Black area holds {{Cl|XOR (boolean)|XOR}} colors, white displays background
BitsOver = wide& {{Cl|MOD}} 32
{{Cl|IF}} BitsOver {{Cl|THEN}} ZeroPAD$ = {{Cl|SPACE$}}((32 - BitsOver) \ 8) 'look for sizes not multiples of 32 bits
{{Cl|_DEST}} bmp&
{{Cl|IF}} BPP < 24 {{Cl|THEN}} {{Cl|PALETTE}} ' 'remove for a PUT using previous {{Cl|XOR (boolean)|XOR}} mask palette data
y = deep& - 1: a$ = " ": p$ = " "
{{Cl|DO}}
x = 0
{{Cl|DO}}
{{Cl|GET}} #1, , a$
Byte{{Cl|VAL}} = {{Cl|ASC}}(a$) 'MSBit is left when calculating 16 X 16 cursor map 2 byte integer
{{Cl|FOR...NEXT|FOR}} Bit% = 7 {{Cl|TO}} 0 {{Cl|STEP}} -1 'values despite M$ documentation that says otherwise!
{{Cl|IF}} Byte{{Cl|VAL}} {{Cl|AND}} 2 ^ Bit% {{Cl|THEN}} '{{Cl|LONG}} values cannot be used in a cursor file!
{{Cl|IF}} BPP > 8 {{Cl|THEN}} {{Cl|PSET}} (x, y), {{Cl|_RGB32}}(255, 255, 255) {{Cl|ELSE}} {{Cl|PSET}} (x, y), 15
{{Cl|ELSE}}: {{Cl|IF}} BPP > 8 {{Cl|THEN}} {{Cl|PSET}} (x, y), {{Cl|_RGB32}}(0, 0, 0) {{Cl|ELSE}} {{Cl|PSET}} (x, y), 0
{{Cl|END IF}}
x = x + 1 '16 X 16 = 32 bytes, 32 X 32 = 128 bytes {{Cl|AND (boolean)|AND}} MASK SIZES
{{Cl|NEXT}} Bit% '48 X 48 = 288 bytes, 64 X 64 = 512 bytes, 128 X 128 = 2048 bytes
{{Cl|LOOP}} {{Cl|WHILE}} x < wide&
{{Cl|GET}} #1, , ZeroPAD$ '16 X 16 and 48 X 48 = 2 byte end padder per row in the {{Cl|AND (boolean)|AND}} MASK
y = y - 1 'adds 32 and 96 bytes respectively to the raw data size!
{{Cl|LOOP}} {{Cl|UNTIL}} y = -1
{{Cl|END SUB}}
{{Cl|SUB}} True{{Cl|COLOR}} ' ' 16 Million colors. NO {{Cl|PALETTE}}! Colored by pixels (24 or 32 BPP)
{{Cl|_DEST}} bmp&
{{Cl|IF}} ((BMP.PWidth * 3) {{Cl|MOD}} 4) <> 0 {{Cl|THEN}} '3 byte pixels
ZeroPAD$ = {{Cl|SPACE$}}((4 - ((BMP.PWidth * 3) {{Cl|MOD}} 4)))
{{Cl|END IF}}
R$ = " ": G$ = " ": B$ = " "
y = deep& - 1
{{Cl|DO}}
x = 0
{{Cl|DO}}
{{Cl|GET}} #1, , B$ '3 bytes set RGB color intensities
{{Cl|GET}} #1, , G$
{{Cl|GET}} #1, , R$
red& = {{Cl|ASC}}(R$)
green& = {{Cl|ASC}}(G$)
blue& = {{Cl|ASC}}(B$)
{{Cl|PSET}} (x, y), {{Cl|_RGB}}(red&, green&, blue&) 'returns closest attribute in 4 or 8 bit
x = x + 1
{{Cl|LOOP}} {{Cl|WHILE}} x < wide&
{{Cl|GET}} #1, , ZeroPAD$ ' 'prevents odd width image skewing
y = y - 1
{{Cl|LOOP}} {{Cl|UNTIL}} y = -1
{{Cl|END SUB}} '' ''
{{Cl|REM}} {{Cl|$INCLUDE}}: '32BitSUB.BM'
{{CodeEnd}}
{{TextStart}}
'*********************************** 32BitSUB.BM INCLUDE FILE *******************************
{{Cb|SUB}} ThirtyTwoBit (x1%, y1%, x2%, y2%, image&, Filename$)
{{Cb|DIM}} Colors8%(255)
{{Cb|IF}} x1% > x2% {{Cb|THEN}} {{Cb|SWAP}} x1%, x2%
{{Cb|IF}} y1% > y2% {{Cb|THEN}} {{Cb|SWAP}} y1%, y2%
{{Cb|_SOURCE}} image&
pixelbytes& = {{Cb|_PIXELSIZE}}(image&)
{{Cb|IF}} pixelbytes& = 0 {{Cb|THEN}} {{Cb|BEEP}}: {{Cb|EXIT SUB}} 'no text screens
FileType$ = "BM"
QB64$ = "QB64" 'free advertiising in reserved bytes
{{Cb|IF}} pixelbytes& = 1 {{Cb|THEN}} OffsetBITS& = 1078 {{Cb|ELSE}} OffsetBITS& = 54 'no palette in 24/32 bit
InfoHEADER& = 40
PictureWidth& = (x2% - x1%) + 1 ' don't exceed maximum screen resolutions!
PictureDepth& = (y2% - y1%) + 1
NumPLANES% = 1
{{Cb|IF}} pixelbytes& = 1 {{Cb|THEN}} BPP% = 8 {{Cb|ELSE}} BPP% = 24
Compression& = 0
WidthPELS& = 3780
DepthPELS& = 3780
{{Cb|IF}} pixelbytes& = 1 {{Cb|THEN}} NumColors& = 256 '24/32 bit say none
{{Cb|IF}} (PictureWidth& {{Cb|AND (boolean)|AND}} 3) {{Cb|THEN}} ZeroPAD$ = {{Cb|SPACE$}}(4 - (PictureWidth& {{Cb|AND (boolean)|AND}} 3))
ImageSize& = (PictureWidth& + {{Cb|LEN}}(ZeroPAD$)) * PictureDepth&
FileSize& = ImageSIZE& + OffsetBITS&
f = {{Cb|FREEFILE}}
{{Cb|OPEN}} Filename$ {{Cb|FOR (file statement)|FOR}} {{Cb|BINARY}} {{Cb|AS}} #f
{{Cb|PUT}} #f, , FileType$
{{Cb|PUT}} #f, , FileSize&
{{Cb|PUT}} #f, , QB64$
{{Cb|PUT}} #f, , OffsetBITS&
{{Cb|PUT}} #f, , InfoHEADER&
{{Cb|PUT}} #f, , PictureWidth&
{{Cb|PUT}} #f, , PictureDepth&
{{Cb|PUT}} #f, , NumPLANES%
{{Cb|PUT}} #f, , BPP%
{{Cb|PUT}} #f, , Compression&
{{Cb|PUT}} #f, , ImageSize&
{{Cb|PUT}} #f, , WidthPELS&
{{Cb|PUT}} #f, , DepthPELS&
{{Cb|PUT}} #f, , NumColors&
{{Cb|PUT}} #f, , SigColors& '51 offset
{{Cb|IF}} pixelbytes& = 1 {{Cb|THEN}} '4 or 8 BPP Palettes set for 256 colors
u$ = {{Cb|CHR$}}(0)
{{Cb|FOR...NEXT|FOR}} c& = 0 {{Cb|TO}} 255 'PUT as BGR order colors
cv& = {{Cb|_PALETTECOLOR (function)|_PALLETTECOLOR}}(c&, image&)
Colr$ = {{Cb|CHR$}}({{Cb|_BLUE32}}(cv&))
{{Cb|PUT}} #f, , Colr$
Colr$ = {{Cb|CHR$}}({{Cb|_GREEN32}}(cv&))
{{Cb|PUT}} #f, , Colr$
Colr$ = {{Cb|CHR$}}({{Cb|_RED32}}(cv&))
{{Cb|PUT}} #f, , Colr$
{{Cb|PUT}} #f, , u$ 'Unused byte
{{Cb|NEXT}}
{{Cb|END IF}}
{{Cb|FOR...NEXT|FOR}} y% = y2% {{Cb|TO}} y1% {{Cb|STEP}} -1 'place bottom up
{{Cb|FOR...NEXT|FOR}} x% = x1% {{Cb|TO}} x2%
c& = {{Cb|POINT}}(x%, y%)
{{Cb|IF}} pixelbytes& = 1 {{Cb|THEN}}
a$ = {{Cb|CHR$}}(c&)
Colors8%({{Cb|ASC}}(a$)) = 1
{{Cb|ELSE}} : a$ = {{Cb|LEFT$}}({{Cb|MKL$}}(c&), 3)
{{Cb|END IF}}
{{Cb|PUT}} #f, , a$
{{Cb|NEXT}}
{{Cb|PUT}} #f, , ZeroPAD$
{{Cb|NEXT}}
{{Cb|FOR...NEXT|FOR}} n = 0 {{Cb|TO}} 255
{{Cb|IF}} Colors8%(n) = 1 {{Cb|THEN}} SigColors& = SigColors& + 1
{{Cb|NEXT}} n
{{Cb|PUT}} #f, 51, SigColors&
{{Cb|CLOSE}} #f
{{Cb|END SUB}} '' ''
'' ''
{{TextEnd}}
{{small|Adapted from code by Bob Seguin}}
<center>'''If full code is not displayed, refresh browser!'''</center>
<center>'''NOTE: Black areas of an image may become "see through" unless another color attribute is used and set to black!'''</center>
: This can be done by changing another color attribute's RGB settings to 0 or almost 0 and creating a mask after using it in solid black areas of a 4 or 8 BPP palette image. This can also be done using [[_PUTIMAGE]] with 32 bit [[_CLEARCOLOR]] settings.
<center>''See the following page:'' [[Creating Sprite Masks]]</center>
==Icon to Bitmap Conversion Function==
The following program uses a conversion function with the [[TYPE]] definitions inside of the function to eliminate an [[$INCLUDE]] library file.
{{CodeStart}}
{{Cl|SCREEN}} {{Cl|_NEWIMAGE}}(640, 480, 256)
{{Cl|_TITLE}} "Icon Converter"
icon$ = "daphne.ico" '<<<<<<<<< change icon file name
bitmap$ = "tempfile.bmp"
indx% = 5 '1 minimum <<<<<<< higher values than count get highest entry image in icon file
{{Cl|IF...THEN|IF}} Icon2BMP(icon$, bitmap$, indx%) {{Cl|THEN}}
img& = {{Cl|_LOADIMAGE}}(bitmap$)
{{Cl|PRINT}} img&
{{Cl|IF...THEN|IF}} img& < -1 {{Cl|THEN}} ' check that handle value is good before loading
{{Cl|_ICON}} img& ' place image in header
{{Cl|_PUTIMAGE}} (300, 250), img& 'place image on screen
{{Cl|_FREEIMAGE}} img& ' always free unused handles to save memory
'{{Cl|KILL}} bitmap$ ' comment out and/or rename to save the bitmaps
{{Cl|END IF}}
{{Cl|ELSE}} {{Cl|PRINT}} "Could not create bitmap!"
{{Cl|END IF}}
{{Cl|END}}
' ----------------------------------------------------
{{Cl|FUNCTION}} Icon2BMP% (filein {{Cl|AS}} {{Cl|STRING}}, fileout {{Cl|AS}} {{Cl|STRING}}, index {{Cl|AS}} {{Cl|INTEGER}})
{{Cl|TYPE}} ICONTYPE ' Icon or cursor file header
Reserved {{Cl|AS}} {{Cl|INTEGER}} ' Reserved (always 0)
ID {{Cl|AS}} {{Cl|INTEGER}} ' Resource ID (Icon = 1, Cursor = 2)
Count {{Cl|AS}} {{Cl|INTEGER}} ' Number of icon bitmaps in Directory of icon entries array
{{Cl|END}} {{Cl|TYPE}} '6 bytes
{{Cl|TYPE}} ENTRYTYPE ' or unanimated Cursor entry (ANI are animated cursors)
Wide {{Cl|AS}} {{Cl|_UNSIGNED}} {{Cl|_BYTE}} ' Width of icon in pixels (USE THIS) Use {{Cl|_UNSIGNED}} over 127
High {{Cl|AS}} {{Cl|_UNSIGNED}} {{Cl|_BYTE}} ' Height of icon in pixels (USE THIS) Use {{Cl|_UNSIGNED}} over 127
NumColors {{Cl|AS}} {{Cl|_BYTE}} ' Maximum number of colors. (2, 8 or 16 colors. 256 or 24/32 bit = 0)
RES2 {{Cl|AS}} {{Cl|_BYTE}} ' Reserved. Not used (always 0)
HotSpotX {{Cl|AS}} {{Cl|INTEGER}} ' Icon: NumberPlanes(normally 0), Cursor: hotspot pixels from left
HotSpotY {{Cl|AS}} {{Cl|INTEGER}} ' Icon: BitsPerPixel(normally 0), Cursor: hotspot pixels from top
DataSize {{Cl|AS}} {{Cl|LONG}} ' Length of image data in bytes minus Icon and Entry headers (USE THIS)
Offset {{Cl|AS}} {{Cl|LONG}} ' Start Offset byte position of icon bitmap header(add 1 if {{Cl|TYPE}} GET)
{{Cl|END}} {{Cl|TYPE}} '16 bytes
{{Cl|TYPE}} PREHEADER ' Bitmap information not in icon BM header
BM {{Cl|AS}} {{Cl|INTEGER}} ' Integer value changed to "BM" by PUT
Size {{Cl|AS}} {{Cl|LONG}} ' Size of the data file({{Cl|LOF}})
Reser {{Cl|AS}} {{Cl|LONG}}' 2 reserved integers are zero automatically
BOffset {{Cl|AS}} {{Cl|LONG}} ' Start offset of pixel data(next byte)
{{Cl|END}} {{Cl|TYPE}} '14 bytes
{{Cl|TYPE}} BMPHEADER ' Bitmap type header found using entry DataOffset + 1
IconHSize {{Cl|AS}} {{Cl|LONG}} ' size of ICON header (always 40 bytes)
PWidth {{Cl|AS}} {{Cl|LONG}} ' bitmap width in pixels (signed integer).
PDepth {{Cl|AS}} {{Cl|LONG}} ' Total map height in pixels (signed integer is 2 times image height)
NumPlanes {{Cl|AS}} {{Cl|INTEGER}} ' number of color planes. Must be set to 1.
BPP {{Cl|AS}} {{Cl|INTEGER}} ' bits per pixel 1, 4, 8, 16, 24 or 32.(USE THIS)
Compress {{Cl|AS}} {{Cl|LONG}} ' compression method should always be 0.
RAWSize {{Cl|AS}} {{Cl|LONG}} ' size of the raw ICON image data(may only be {{Cl|XOR (boolean)|XOR}} mask size).
Hres {{Cl|AS}} {{Cl|LONG}} ' horizontal resolution of the image(not normally used)
Vres {{Cl|AS}} {{Cl|LONG}} ' vertical resolution of the image(not normally used)
NumColors {{Cl|AS}} {{Cl|LONG}} ' number of colors in the color palette(not normally used)
SigColors {{Cl|AS}} {{Cl|LONG}} ' number of important colors used(not normally used)
{{Cl|END}} {{Cl|TYPE}} '40 bytes palette and image data immediately follow this header!
{{Cl|DIM}} ICON {{Cl|AS}} ICONTYPE, ENT {{Cl|AS}} ENTRYTYPE, PRE {{Cl|AS}} PREHEADER, BMP {{Cl|AS}} BMPHEADER
rf = {{Cl|FREEFILE}}
{{Cl|IF...THEN|IF}} {{Cl|LCASE$}}({{Cl|RIGHT$}}(filein, 4)) = ".ico" {{Cl|THEN}} 'check file extension is ICO only
{{Cl|OPEN}} filein {{Cl|FOR...NEXT|FOR}} {{Cl|BINARY}} {{Cl|ACCESS}} {{Cl|READ}} {{Cl|AS}} rf
{{Cl|ELSE}} {{Cl|EXIT FUNCTION}}
{{Cl|END IF}}
{{Cl|GET}} rf, , ICON 'GET 6 byte icon header
{{Cl|IF...THEN|IF}} ICON.ID <> 1 {{Cl|OR (boolean)|OR}} ICON.Count = 0 {{Cl|THEN}} {{Cl|CLOSE}} rf: {{Cl|EXIT FUNCTION}}
{{Cl|IF...THEN|IF}} index > 0 {{Cl|AND (boolean)|AND}} index <= ICON.Count {{Cl|THEN}} entry = 16 * (index - 1) {{Cl|ELSE}} entry = 16 * (ICON.Count - 1)
{{Cl|PRINT}} ICON.Count, entry
{{Cl|SEEK}} rf, 1 + 6 + entry 'start of indexed Entry header selected
{{Cl|GET}} rf, , ENT 'GET 16 byte Entry Header set by index request or highest available
{{Cl|SEEK}} rf, 1 + ENT.Offset 'go to BMP header offset given in Entry header
{{Cl|GET}} rf, , BMP 'GET 40 byte icon bitmap header information
{{Cl|IF...THEN|IF}} BMP.BPP <= 24 {{Cl|THEN}} pixelbytes = BMP.BPP / 8 {{Cl|ELSE}} pixelbytes = 3
{{Cl|IF...THEN|IF}} BMP.BPP > 1 {{Cl|AND (boolean)|AND}} BMP.BPP <= 8 {{Cl|THEN}} palettebytes = 4 * (2 ^ BMP.BPP) {{Cl|ELSE}} palettebytes = 0
datasize& = (ENT.Wide * ENT.High * pixelbytes) + palettebytes 'no padder should be necessary
filesize& = datasize& + 14 + 40 ' data and palette + header
bmpoffset& = palettebytes + 54 ' data offset from start of bitmap
BMP.PWidth = ENT.Wide
BMP.PDepth = ENT.High
BMP.RAWSize = datasize& - palettebytes
PRE.BM = {{Cl|CVI}}("BM") 'integer value changes to "BM" in file
PRE.Size = filesize&
PRE.BOffset = bmpoffset& 'start of data after header and palette if used
wf = {{Cl|FREEFILE}}
{{Cl|OPEN}} fileout {{Cl|FOR...NEXT|FOR}} {{Cl|BINARY}} {{Cl|AS}} wf
{{Cl|PUT}} wf, , PRE 'PUT 14 byte bitmap information
{{Cl|PUT}} wf, , BMP 'PUT 40 byte bitmap header information
{{Cl|SEEK}} rf, 1 + ENT.Offset + 40
dat$ = {{Cl|STRING$}}(datasize&, 0) 'create string variable the length of remaining image data
{{Cl|GET}} rf, , dat$ 'GET remaining palette and only the XOR image data after the indexed header
{{Cl|PUT}} wf, , dat$ 'PUT remaining data into new bitmap file
{{Cl|CLOSE}} rf, wf
Icon2BMP = ICON.Count 'function returns number of images available in icon file
{{Cl|END FUNCTION}} '' ''
{{CodeEnd}}
{{small|Code by Ted Weissgerber}}
: ''Note:'' The index selected or the highest numbered icon image less than the index value is the image displayed.
==References==
''See also:''
* [[Creating Icons from Bitmaps]]
* [[Bitmaps]], [[Icons and Cursors]]
* [[_CLEARCOLOR]]
* [[_ALPHA]], [[_ICON]]
* [[SaveIcon32]] {{text|(create icons from any image)}}
{{PageNavigation}}