mirror of
https://github.com/QB64Official/qb64.git
synced 2024-09-28 11:17:47 +00:00
114 lines
6.9 KiB
Text
114 lines
6.9 KiB
Text
The following Icon creation procedure was adapted from Galleon's [[SAVEIMAGE]] sup-procedure that creates 8 BPP or 32 bit bitmaps:
|
|
|
|
'''NOTE: QB64 can use .ico files natively for Windows executables with [[$EXEICON]].'''
|
|
{{CodeStart}} '' ''
|
|
DO
|
|
{{Cl|LINE INPUT}} "Use 8 bit(256 colors) or 32 bit image? ", bit$
|
|
clrmode% = {{Cl|VAL}}(bit$)
|
|
{{Cl|LOOP}} {{Cl|UNTIL}} clrmode% = 8 {{Cl|OR (boolean)|OR}} clrmode% = 32
|
|
{{Cl|IF...THEN|IF}} clrmode% = 8 {{Cl|THEN}} clrmode% = 256
|
|
{{Cl|LOCATE}} 10, 10: {{Cl|PRINT}} "Do you wish to make black transparent? (Y/N) ";
|
|
K$ = {{Cl|INPUT$}}(1): {{Cl|PRINT}} K$
|
|
{{Cl|IF...THEN|IF}} {{Cl|UCASE$}}(K$) = "Y" {{Cl|THEN}} mode% = 1
|
|
{{Cl|_DELAY}} 1
|
|
{{Cl|SCREEN}} {{Cl|_NEWIMAGE}}(640, 480, clrmode%)
|
|
DO
|
|
{{Cl|LOCATE}} 10, 10: {{Cl|LINE INPUT}} "Enter the icon size to use(multiple of 16): ", sz$
|
|
size& = {{Cl|VAL}}(sz$)
|
|
{{Cl|LOOP}} {{Cl|UNTIL}} size& {{Cl|MOD}} 16 = 0 AND size& >= 16 AND size& <= 128
|
|
DO
|
|
{{Cl|LOCATE}} 10, 10: {{Cl|LINE INPUT}} "Enter the image file name to convert to an icon: ", BMP$
|
|
{{Cl|CLS}}
|
|
{{Cl|LOOP}} {{Cl|UNTIL}} {{Cl|_FILEEXISTS}}(BMP$)
|
|
img& = {{Cl|_LOADIMAGE}}(BMP$)
|
|
{{Cl|IF...THEN|IF}} img& = -1 {{Cl|OR (boolean)|OR}} img& = 0 {{Cl|THEN}} {{Cl|LOCATE}} 15, 25: {{Cl|PRINT}} "Image failed to load!": {{Cl|END}}
|
|
|
|
{{Cl|IF...THEN|IF}} mode% = 0 THEN {{Cl|CLS}} , {{Cl|_RGB}}(255, 255, 255)
|
|
{{Cl|IF...THEN|IF}} clrmode% = 256 {{Cl|THEN}} {{Cl|_COPYPALETTE}} (img&)
|
|
{{Cl|_PUTIMAGE}} (0, 0)-(size& - 1, size& - 1), img&, 0 '(31, 31), img&, 0 '<<<<<<<<<<<
|
|
|
|
{{Cl|LOCATE}} 20, 10: {{Cl|PRINT}} "Do you want to make an icon out of the image? (Y/N) ";
|
|
K$ = {{Cl|INPUT$}}(1): {{Cl|PRINT}} K$
|
|
{{Cl|IF...THEN|IF}} {{Cl|UCASE$}}(K$) <> "Y" {{Cl|THEN}} {{Cl|END}}
|
|
SaveFile$ = {{Cl|LEFT$}}(BMP$, {{Cl|INSTR}}(BMP$, ".")) + "ico"
|
|
SaveIcon32 img&, size&, mode%, SaveFile$
|
|
|
|
{{Cl|END}}
|
|
' ---------------------------------------------------------
|
|
|
|
{{Cl|SUB}} SaveIcon32 (image {{Cl|AS}} {{Cl|LONG}}, size {{Cl|AS}} {{Cl|LONG}}, mode AS {{Cl|INTEGER}}, filename {{Cl|AS}} {{Cl|STRING}})
|
|
bytesperpixel& = {{Cl|_PIXELSIZE}}(image&)
|
|
{{Cl|IF...THEN|IF}} bytesperpixel& = 0 {{Cl|THEN}} {{Cl|PRINT}} "Text modes unsupported!": {{Cl|END}}
|
|
{{Cl|IF...THEN|IF}} bytesperpixel& = 1 {{Cl|THEN}} bpp& = 8 {{Cl|ELSE}} bpp& = 24 '256 or 32 bit color
|
|
{{Cl|IF...THEN|IF}} size& {{Cl|MOD}} 16 {{Cl|OR}} size& < 16 {{Cl|OR}} size& > 128 THEN {{Cl|PRINT}} "Size not supported!": {{Cl|END}}
|
|
x& = size& 'supports sizes from 16 to 128 only!
|
|
y& = size&
|
|
'Headers: icon count width depth colors cursor hotspots size - offset
|
|
b$= {{Cl|MKI$}}(0)+{{Cl|MKI$}}(1)+{{Cl|MKI$}}(1)+{{Cl|CHR$}}(x&)+{{Cl|CHR$}}(y&)+{{Cl|CHR$}}(0)+{{Cl|CHR$}}(0)+{{Cl|MKI$}}(0)+{{Cl|MKI$}}(0)+"????"+{{Cl|MKL$}}(22) _
|
|
+{{Cl|MKL$}}(40)+{{Cl|MKL$}}(x&)+{{Cl|MKL$}}(2 * y&)+{{Cl|MKI$}}(1)+{{Cl|MKI$}}(bpp&)+{{Cl|MKL$}}(0)+"????" + {{Cl|STRING$}}(16, 0)
|
|
'BMP size width double height plane BPP raw size
|
|
{{Cl|IF...THEN|IF}} bytesperpixel& = 1 {{Cl|THEN}}
|
|
{{Cl|FOR...NEXT|FOR}} c& = 0 {{Cl|TO}} 255 ' read BGR color settings from image + 1 byte spacer({{Cl|CHR$}}(0))
|
|
cv& = {{Cl|_PALETTECOLOR (function)|_PALETTECOLOR}}(c&, image&) ' color attribute to read.
|
|
b$ = b$ + {{Cl|CHR$}}({{Cl|_BLUE32}}(cv&)) + {{Cl|CHR$}}({{Cl|_GREEN32}}(cv&)) + {{Cl|CHR$}}({{Cl|_RED32}}(cv&)) + {{Cl|CHR$}}(0) 'spacer
|
|
{{Cl|NEXT}}
|
|
{{Cl|END IF}}
|
|
lastsource& = {{Cl|_SOURCE}}
|
|
{{Cl|_SOURCE}} 0 'set source as program screen. Do NOT use loaded image handle as size has changed!
|
|
{{Cl|IF...THEN|IF}} ((x& * 3) {{Cl|MOD}} 4) {{Cl|THEN}} padder$ = {{Cl|STRING$}}(4 - ((x& * 3) {{Cl|MOD}} 4), 0)
|
|
{{Cl|FOR...NEXT|FOR}} py& = y& - 1 {{Cl|TO}} 0 {{Cl|STEP}} -1 ' read target image pixel color data
|
|
r$ = ""
|
|
{{Cl|FOR...NEXT|FOR}} px& = 0 {{Cl|TO}} x& - 1
|
|
c& = {{Cl|POINT}}(px&, py&)
|
|
{{Cl|IF...THEN|IF}} bytesperpixel& = 1 {{Cl|THEN}} r$ = r$ + {{Cl|CHR$}}(c&) {{Cl|ELSE}} r$ = r$ + {{Cl|LEFT$}}({{Cl|MKL$}}(c&), 3)
|
|
{{Cl|NEXT}} px&
|
|
d$ = d$ + r$ + padder$
|
|
{{Cl|NEXT}} py&
|
|
{{Cl|IF...THEN|IF}} (x& {{Cl|MOD}} 32) {{Cl|THEN}} bitpad& = 32 - (x& {{Cl|MOD}} 32) 'padder bits when not multiples of 32
|
|
{{Cl|IF...THEN|IF}} mode% {{Cl|THEN}} 'make black pixels white in AND mask so they become transparent
|
|
{{Cl|FOR...NEXT|FOR}} py& = y& - 1 {{Cl|TO}} 0 {{Cl|STEP}} -1 'read image to find black pixels
|
|
px& = 0
|
|
{{Cl|DO...LOOP|DO}}: byte% = 0
|
|
{{Cl|FOR...NEXT|FOR}} bit% = 7 {{Cl|TO}} 0 {{Cl|STEP}} -1 'change transparent color to suit your needs
|
|
byte% = 2 * byte% - ({{Cl|POINT}}(px&, py&) = {{Cl|_RGB}}(0, 0, 0)) 'bitpacking adds 1 when true
|
|
px& = px& + 1
|
|
{{Cl|NEXT}}
|
|
a$ = a$ + {{Cl|CHR$}}(byte%)
|
|
{{Cl|LOOP}} {{Cl|WHILE}} px& < x& - 1
|
|
{{Cl|IF...THEN|IF}} bitpad& {{Cl|THEN}} a$ = a$ + {{Cl|STRING$}}((bitpad& + 7) \ 8, 0) 'add padder at end of row when necessary
|
|
{{Cl|NEXT}}
|
|
{{Cl|ELSE}} a$ = {{Cl|STRING$}}(y& * ((x& + bitpad& + 7) \ 8), 0) 'totally black {{Cl|AND (boolean)|AND}} mask
|
|
{{Cl|END IF}}
|
|
d$ = d$ + a$
|
|
{{Cl|_SOURCE}} lastsource&
|
|
{{Cl|MID$}}(b$, 43, 4) = {{Cl|MKL$}}({{Cl|LEN}}(d$)) 'raw image size with {{Cl|AND}} mask
|
|
b$ = b$ + d$ ' total file data bytes to create file
|
|
{{Cl|MID$}}(b$, 15, 4) = {{Cl|MKL$}}({{Cl|LEN}}(b$) - 22) ' size of data file minus Entry header offset
|
|
{{Cl|IF...THEN|IF}} {{Cl|LCASE$}}({{Cl|RIGHT$}}(filename$, 4)) <> ".ico" {{Cl|THEN}} ext$ = ".ico"
|
|
f& = {{Cl|FREEFILE}}
|
|
{{Cl|OPEN}} filename$ + ext$ {{Cl|FOR...NEXT|FOR}} {{Cl|OUTPUT}} {{Cl|AS}} #f&: {{Cl|CLOSE}} #f& ' erases an existing file
|
|
{{Cl|OPEN}} filename$ + ext$ {{Cl|FOR...NEXT|FOR}} {{Cl|BINARY}} {{Cl|AS}} #f&
|
|
{{Cl|PUT}} #f&, , b$
|
|
{{Cl|CLOSE}} #f&
|
|
{{Cl|END SUB}} '' ''
|
|
{{CodeEnd}}
|
|
{{small|Code by Ted Weissgerber}}
|
|
|
|
:''Explanation:'' The icons created can have a full black [[AND]] mask for a solid square image when mode% is zero. If mode% is a value other than 0, the AND mask routine looks for black pixels and sets the background pixel on for transparency. Icons with dimensions that are not a multiple of 32 would require padding. In the header, ???? is later replaced with size data. If the image is 24/32 BPP, the size of the [[XOR]] image data will triple because each pixel uses 3 bytes for red, green and blue values up to 255.
|
|
:{{text|To create '''.CUR''' cursor files change the second value from 1 to 2 and set the 2 cursor click hotspot offset [[INTEGER]] values.|purple}}
|
|
|
|
|
|
:Icons that are 16 X 16 or 48 X 48 require 2 padder bytes to be added at the end of each row increasing data size by 32 and 96.
|
|
|
|
|
|
''See also:''
|
|
|
|
*[[_ICON]], [[$EXEICON]]
|
|
*[[SAVEIMAGE]]
|
|
*[[Icons and Cursors]]
|
|
*[[Resource Table extraction|Resource Extraction]]
|
|
*[[Bitmaps]]
|
|
*[[GIF Images]]
|
|
|
|
|
|
{{PageNavigation}}
|