Page 1 of 1
how to save ico file?
Posted: Fri Nov 24, 2023 11:37 pm
by AZJIO
wiki
solution by @srod
solution by @idle
Code: Select all
EnableExplicit
UsePNGImageEncoder()
#Image = 0
Global tmp$
Global XXX = 16
Global YYY = 16
Procedure SaveICO(Path$)
Protected *Buffer
#File = 0
If CreateFile(#File, Path$)
WriteUnicodeCharacter(#File, 0)
WriteUnicodeCharacter(#File, 1)
WriteUnicodeCharacter(#File, 1)
WriteByte(#File , XXX)
WriteByte(#File , YYY)
WriteByte(#File , 0)
WriteByte(#File , 0)
WriteUnicodeCharacter(#File, 0)
WriteUnicodeCharacter(#File, 32)
WriteLong(#File, XXX * YYY)
WriteLong(#File, 16)
*Buffer = EncodeImage(#Image, #PB_ImagePlugin_PNG, 10, 32)
WriteData(#File, *Buffer, MemorySize(*Buffer))
CloseFile(#File)
EndIf
EndProcedure
tmp$ = SaveFileRequester("Select file to save", GetCurrentDirectory(), "*.ico|*.ico", 0)
If Asc(tmp$)
If CreateImage(#Image, XXX, YYY, 32)
If StartDrawing(ImageOutput(#Image))
Box(0, 0, XXX, YYY, $00FF00) ; Green
StopDrawing()
If Right(tmp$, 4) <> ".ico"
tmp$ + ".ico"
EndIf
SaveICO(tmp$)
EndIf
EndIf
EndIf
Edit: solution added by @idle. See the link at the beginning of the post
Re: how to save ico file?
Posted: Sat Nov 25, 2023 12:58 am
by HeX0R
You seem to have serious problems understanding the board structure here.
Some of your applications are in General Discussion, why? (=> "Applications - Feedback and Discussion"?)
Some of your codes are in General Discussion, why? (=> "Tricks 'n' Tips"?)
Now you are adding a thread to coding questions, but answering it yourself in the first post? (=> "Tricks 'n' Tips"?)
Don't get me wrong, some of your provided stuff is pretty cool, but in the end no one will find it, because most of them are just misplaced.
Re: how to save ico file?
Posted: Sat Nov 25, 2023 1:33 am
by AZJIO
Now you are adding a thread to coding questions, but answering it yourself in the first post?
I think you can guess. I post a question that I previously tested in my program for an hour, or maybe more, using different methods. I understand that I can’t do it and the search doesn’t give results, so I ask a question. But at the same time, why do you think that I should stop? I change the search methods, use the Google query "ico site:purebasic.fr/english" and look through 5 pages of results and finally I found the function. Of course, I try to save you from useless work by posting useful results. This function had just worked for me and I wanted to post the code using this function, but something broke again. Initially, I changed 24 to 32 and the function began to work. And now I'm reviewing the code in which I changed almost nothing and trying to understand why it doesn't work.
The function uses an icon descriptor, and I give it an image descriptor. So I haven't gotten the perfect answer yet and am tweaking the image to make it look like an icon handle.
Some of your applications are in General Discussion, why? (=> "Applications - Feedback and Discussion"?)
Some of your codes are in General Discussion, why? (=> "Tricks 'n' Tips"?)
What year is the message from? Previously, I posted it in the discussion section, but I was advised to post it in the applications section, since I am giving a ready-made application. On the other hand, the source code is not posted in the applications section, but only the executable file. In this case, my source code is more suitable for the “Tricks 'n' Tips” section. Attention, question, if you have a logic for where to put it, then just express it, but don’t make me guess your thoughts, I acted based on my understanding.
By the way, the "Tricks 'n' Tips" section is a bit of an unusual name to put the functionality in the section, perhaps this is a translation problem into Russian.
This code does not allow you to create an icon from an image
Code: Select all
If Not GetIconInfo_(hIcon, iconinfo)
Debug 1
ProcedureReturn 0
EndIf ; Not a valid icon handle.
Re: how to save ico file?
Posted: Mon Nov 27, 2023 5:12 pm
by infratec
But your code is wrong und buggy.
The offset is not 16, it is $16
Your size of the data is wrong.
You allocate memory but don't free it.
You use a fixed number as file but you can not be sure that an ohter code use already the same.
A corrected version:
Code: Select all
; https://www.purebasic.fr/english/viewtopic.php?t=82936
; https://en.wikipedia.org/wiki/ICO_(file_format)
EnableExplicit
UsePNGImageEncoder()
Procedure.i SaveICO(Filename$, Image.i)
Protected Result.i, File.i, *Buffer
If IsImage(Image)
File = CreateFile(#PB_Any, Filename$)
If File
; Header
WriteUnicodeCharacter(File, 0) ; Reserved. Must always be 0.
WriteUnicodeCharacter(File, 1) ; Specifies image type: 1 for icon (.ICO) image, 2 for cursor (.CUR) image. Other values are invalid.
WriteUnicodeCharacter(File, 1) ; Specifies number of images in the file.
; Directory
WriteByte(File , ImageWidth(Image)) ; Width
WriteByte(File , ImageHeight(Image)) ; Height
WriteByte(File , 0) ; Specifies number of colors in the color palette. Should be 0 if the image does not use a color palette.
WriteByte(File , 0) ; Reserved, should be 0
WriteUnicodeCharacter(File, 0) ; Specifies color planes. Should be 0 or 1
WriteUnicodeCharacter(File, 32) ; Specifies bits per pixel.
*Buffer = EncodeImage(Image, #PB_ImagePlugin_PNG, 9, 32)
If *Buffer
WriteLong(File, MemorySize(*Buffer)) ; Size of the bitmap data in bytes.
WriteLong(File, Lof(File) + SizeOf(Long)) ; Offset in the file.
If WriteData(File, *Buffer, MemorySize(*Buffer)) = MemorySize(*Buffer)
Result = #True
EndIf
FreeMemory(*Buffer)
EndIf
CloseFile(File)
If Not Result
DeleteFile(Filename$)
EndIf
EndIf
EndIf
ProcedureReturn Result
EndProcedure
#Image = 0
Define tmp$
Define XXX.i = 16
Define YYY.i = 16
tmp$ = SaveFileRequester("Select file to save", GetCurrentDirectory(), "*.ico|*.ico", 0)
If tmp$
If Right(tmp$, 4) <> ".ico"
tmp$ + ".ico"
EndIf
If CreateImage(#Image, XXX, YYY, 32, #PB_Image_Transparent)
If StartDrawing(ImageOutput(#Image))
DrawingMode(#PB_2DDrawing_AllChannels )
Circle(XXX / 2, YYY / 2, XXX / 3 , RGBA(0,255,0,255))
StopDrawing()
SaveICO(tmp$, #Image)
EndIf
EndIf
EndIf
Re: how to save ico file?
Posted: Mon Nov 27, 2023 5:23 pm
by Mijikai
I would suggest to use structs.
Some old code with structs but limited functionality:
http://forums.purebasic.com/german/view ... 2d#p350902
Re: how to save ico file?
Posted: Wed Nov 29, 2023 12:02 am
by HeX0R
AZJIO wrote: Sat Nov 25, 2023 1:33 am
Attention, question, if you have a logic for where to put it, then just express it, but don’t make me guess your thoughts, I acted based on my understanding.
Guess my thoughts?
I think I made pretty clear where all those threads should go to from my point of view (did you see those remarks in parentheses?)
Anyway, I don't care, I'm not a moderator, it was advice, nothing more.
Take it or leave it!
And a rhetorical question from my side, if you don't mind:
If everyone but you seems to know exactly where to place their topics, who has to "express" himself then?
Re: how to save ico file?
Posted: Wed Nov 29, 2023 1:51 am
by AZJIO
HeX0R
Can make a separate topic for communication where to place the code?
Re: how to save ico file?
Posted: Wed Nov 29, 2023 4:55 am
by idle
make an png ico pack with sizes 16 to 256
Code: Select all
;make a ico pack out of a image image should be square 32 bit depth
EnableExplicit
Structure ICONDIR
res.u
type.u
num.u
EndStructure
Structure ICONDIRECTORYENTRY
width.a
height.a
numcolors.a
res.a
colorplanes.u
bitsperpixel.u
size.l
offset.l
EndStructure
Structure ICONData
header.ICONDIR
icons.ICONDIRECTORYENTRY[5]
EndStructure
Structure bufs
*buffer[5]
EndStructure
UsePNGImageEncoder()
UsePNGImageDecoder()
Procedure CreateIconFile(file.s,image)
Protected ico.ICONData
Protected sz = 16
Protected buf.bufs
Protected timg,fn, offset,a,b
offset = SizeOf(ICONData)
ico\header\num=5
ico\header\type=1
offset = SizeOf(ICONData)
If file <> ""
fn = CreateFile(#PB_Any,file)
If fn
Repeat
timg = CopyImage(image,#PB_Any)
If timg
If ResizeImage(timg,sz,sz,#PB_Image_Smooth)
buf\buffer[a] = EncodeImage(timg, #PB_ImagePlugin_PNG, 0, 32)
EndIf
Else
For b = 0 To a
If buf\buffer[a]
FreeMemory(buf\buffer[a])
EndIf
Next
CloseFile(fn)
ProcedureReturn 0
EndIf
FreeImage(timg)
ico\icons[a]\width = sz
ico\icons[a]\height = sz
ico\icons[a]\colorplanes = 1
ico\icons[a]\bitsperpixel = 32
ico\icons[a]\size = MemorySize(buf\buffer[a])
ico\icons[a]\offset = offset
offset + ico\icons[a]\size
a+1
sz << 1
Until a = 5
a=0
WriteData(fn,@ico,SizeOf(ICONData))
Repeat
WriteData(fn,Buf\buffer[a],ico\icons[a]\size)
FreeMemory(Buf\buffer[a])
a+1
Until a = 5
CloseFile(fn)
EndIf
ProcedureReturn 1
EndIf
EndProcedure
Global image,file$
image = CreateImage(#PB_Any,512,512,32)
StartDrawing(ImageOutput(image))
DrawingMode(#PB_2DDrawing_AllChannels )
Circle(512 / 2, 512 / 2, 512 / 3 , RGBA(0,255,0,255))
StopDrawing()
file$ = "e:\test.ico"
CreateIconFile(file$,image)
Re: how to save ico file?
Posted: Wed Nov 29, 2023 6:05 am
by Kuron
The criticism could have been handled better, or privately. He is not as bad as others who spam multiple forums with advertisements for their products.
He is a user who is very enthusiastic about PB, is willing to share what he learns, is willing to learn in general and has released some really nice little programs. He is not somebody who needs to be jumped on.
If you do NOT like somebody's posts, the forum has a wonderful ignore feature, put the person on your "foe" list and you will never see their posts again.
Keep in mind much gets lost in translation. RELAX! We are supposed to be on the same team here.
Re: how to save ico file?
Posted: Wed Nov 29, 2023 6:43 am
by idle
I agree Kuron but this isn't the place to discuss it. So I will answer the question which nobody has actually done it yet.
And here's is a partial solution to create a png icon pack from a square image.
Code: Select all
;make a ico pack out of a image image should be square 32 bit depth
EnableExplicit
Structure ICONDIR
res.u
type.u
num.u
EndStructure
Structure ICONDIRECTORYENTRY
width.a
height.a
numcolors.a
res.a
colorplanes.u
bitsperpixel.u
size.l
offset.l
EndStructure
Structure ICONData
header.ICONDIR
icons.ICONDIRECTORYENTRY[5]
EndStructure
Structure bufs
*buffer[5]
EndStructure
UsePNGImageEncoder()
UsePNGImageDecoder()
Procedure CreateIconFile(file.s,image)
Protected ico.ICONData
Protected sz = 16
Protected buf.bufs
Protected timg,fn, offset,a,b
offset = SizeOf(ICONData)
ico\header\num=5
ico\header\type=1
offset = SizeOf(ICONData)
If file <> ""
fn = CreateFile(#PB_Any,file)
If fn
Repeat
timg = CopyImage(image,#PB_Any)
If timg
If ResizeImage(timg,sz,sz,#PB_Image_Smooth)
buf\buffer[a] = EncodeImage(timg, #PB_ImagePlugin_PNG, 0, 32)
EndIf
Else
For b = 0 To a
If buf\buffer[a]
FreeMemory(buf\buffer[a])
EndIf
Next
CloseFile(fn)
ProcedureReturn 0
EndIf
FreeImage(timg)
ico\icons[a]\width = sz
ico\icons[a]\height = sz
ico\icons[a]\colorplanes = 1
ico\icons[a]\bitsperpixel = 32
ico\icons[a]\size = MemorySize(buf\buffer[a])
ico\icons[a]\offset = offset
offset + ico\icons[a]\size
a+1
sz << 1
Until a = 5
a=0
WriteData(fn,@ico,SizeOf(ICONData))
Repeat
WriteData(fn,Buf\buffer[a],ico\icons[a]\size)
FreeMemory(Buf\buffer[a])
a+1
Until a = 5
CloseFile(fn)
EndIf
ProcedureReturn 1
EndIf
EndProcedure
Global image,file$
image = CreateImage(#PB_Any,512,512,32)
StartDrawing(ImageOutput(image))
DrawingMode(#PB_2DDrawing_AllChannels )
Circle(512 / 2, 512 / 2, 512 / 3 , RGBA(0,255,0,255))
StopDrawing()
file$ = "d:\test.ico"
CreateIconFile(file$,image)
Re: how to save ico file?
Posted: Thu Nov 30, 2023 7:48 am
by Denis
Normally, icons with a size< 256/256 should not be compressed (Microsoft's compressed icon format is png).
see here
https://www.axialis.com/tutorials/windo ... s.html#t2
If I remember what I did with my PureIconManager utility, to recreate an icon by decompressing it, you need to extract the image and create the image mask, recalculate the sizes and modify the size and offset in the header.
I tested a lot of decompressed icons with different software (Axialis etc.) but for each software the mask was different during decompression, so I thought about and adopted a way of creating the mask.