Icon file format research

xiaoxiao2021-03-06  56

[Original documentation, do not repost to other sites] Often see someone says that the icon file is a normal bitmap file. I don't know why this is said. In fact, the icon file does have a bit like a bitmap file, but it still has its own expression structure. The beginning of the icon file is a strange format, defined as follows: tagicondir = record idreserved: word; idtype: word; idcount: word; ideentries: array [0..0] of tagicondirentry; end; where IDReServed is a reserved domain, current Always 0, IDTYPE is defined as file type as bitmap file, but is defined as a resource type, is an icon, it is $ 0001, it is a cursor, it is $ 0002, which is visible, when defined this type, MS It is determined by the resource class file, it is estimated that the reason why the beginning of a reserved domain is left at the beginning, and it is also the definition method of the reference bitmap file format, but I don't know why I have not given this reserved domain officially determine the name. IDCount said that the file contains several icons, the earliest time, it has always been $ 0002, which is a common 16x16 and a 32x32 two bitmap icon, now some icons, such as in XP, already up to up to 8 bitmaps. Next is an array structure of Identries. The size of this structure is not an array that starts with 1, which needs to determine the real array size based on the number of icons (idcount). In order to deepen understanding, let us look at a Windows98 to install an icon in the Windows directory: WinUpd.ico beginning of 22byte case: 00 00 01 00 06 00 20 20 10 00 00 00 00 00 E8 02 00 00 66 00 00 00 The red part is that the domain idReServed, the green part is the resource type idType, and the purple means that this file contains the number of icons Idcount, which is a $ 6, indicating that it contains 6 icons. The back is the first idener array (because there are 6 icons, there should always have 6 such IDENTRIES arrays). Let's take a look at how the IDEntries array is defined: tagicondirentry = record bwidth: Byte; // icon display width BHEIGHT: BYTE; // icon image display height bcolorcount: Bryte; // icon picture Color number breserved : Byte; // Reserved domain always 0 wplanes: word; // icon sequence number wbitcount: word; // icon color depth dwbytesinres: dword; // icon image occupied data DWImageoffset: dWord; / / Icon Picture The start position end; this structure is a very fixed 16byte data, and its respective meaning has been marked. Since each icon in the same file has such a structure, it actually refers to the specific information of a single icon. I don't know why, Microsoft has never had a formal document to declare the above structure definition, John _ Hornick writes the only one written by VC developers in 95 years, became all the developers who are interested in icons. Bible.

Because some definitions in the above structure have maintained the most primitive idea of ​​its initial designer, Borland jumped out of MS constraints in their Win32 development environment, defined a can coexist with Canvas. Icon class - TiconImage, thus destined that Borland will interpret icons in its own way. Behind we will see that tagicondirentry has been absorbed by the core API of the MS as a formal member, except for 2 members of DWBytesinRes and DwImageOffset, and these two members are also written as MS files. The purpose of the API. Therefore, as MS it is said, the icon file is a member of the shell, which is only valid when the shell exists. (one)

[Original documentation, please do not repost to other sites] As we talked over, the icon is a member of the shell, and the shell is in reading the file, which determines how to explain this file based on the extension. When you encounter an ICO file, it reads the second word byte of the file to determine if the resource type is $ 0001 or $ 0002. After determining, further read the third Word byte to assign enough to IdeNtries. Memory: Identries' memory allocation = tagicondir.idcount * Sizeof (tagicondirentry) Since tagicondirentry is always 16byte, the number of memory is all associated with IDCount. Based on this, we can read a continuous plurality of Tagicondirentry contents to determine the start position of each icon image and the total amount of information contained (dWbytesinRes). Get the start position of the icon picture, you can read the contents of this image. Icon pictures, actually is a picture of bitmap format. Continue to use the Winupd.ico icon in the above example as an example, starting from the 7th Byte, is the first IDENTRIES: 20 20 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000 00 00 Find dwbytesinres = 000002E8 and dwimageoffset = 00000066. That is, the item $ 66 bytes starting from the beginning of the file, to $ 34E, is the first content of the first icon picture. This content is a standard bitmap format. In order to distinguish between a formal bitmap format, we call it TagiconImage (notice that you have confused with Borland): tagiconimage = record ichead: TbitMapInfoHeader; iccolors: array [0..0 ] of trgquad; ICXOR: Array [0..0] of byte; icand: array [0..0] of byte; end; From the above structure we will find 2 members of ICXOR and ICAND. Ordinary bitmap information is not these 2 members. What did they represent? That's right, guess can guess, this is 2 position image line information. Everyone knows that the icon is displayed when it is displayed, using the mask method to display the 2 deputy bit map in the same location, first using the XOR bit map out of the area that needs to be displayed, and then in the area of ​​the exit The graphical shown is displayed. Due to this, the bitmapinfoheader in the bitmap format of the icon is shared by 2 bits. It is the biggest difference between the ordinary bitmap header information is a member of TbitmapInfoHeader.biHeight, apparent that it is the sum of 2 paralgraphic heights. Since I don't plan to say in a bitmap format here, please refer to the "Bitmap File Format Research". In one of the following, I will use the knowledge introduced above, directly according to this ICON's format specification, use a true color graph, assemble a self-icon. (of two)

[Original documentation, please do not repost to other sites] Based on the research on the Windows Drawing API, we can get a basic fact, that is, the bottom drawing operation DrawDIB. DrawDibdraw is the most direct call function for all bit drawings of Windows, which only requires TbitMapInfoHeader. After deep-in-depth palette mode and true color mode, we can realize that Windows is sufficient to get information from the bitmap information header, which is to explain how the data will be processed. If it is a palette mode, the subsequent data contains a palette and a pixel point color index. If it is true color, the subsequent data is directly the RGB color value of the pixel point. Knowing this situation, we can simply understand the icon graphics structure (tagiconimage) mentioned above as bitmap information (tagbitmapinfo). These two structures were originally descriptated in the color chart. When the real color age, the MS did not move the position of the palette to the position of the palette. In this way, a real color bitmap is described, it becomes unusually simple, we don't need to draw a picture at all, but only need to fill the key data to make Windows work very well. The following code, directly pressing any true color bitmap as long as the size is not more than 255 x 255 pixels, and remains unchanged, so the high size of the real bitmap is unchanged, so the real bitmap width is remained unchanged. You can make a true color icon of the maximum 255 x 255. The code is divided into two functions, first feed the obtained bitmap file, first feed the function checkbmp (const ms: tstream): Boolean for bitmap format check, here mainly check the width, high size and compression, check By the way to fill the basic data required for icon format. This format, I am simplified for the iconhand array. Then use the function coalitionico (VAR MS: TMEMORYSTREAM): Boolean's formal bitmap population.

This function of generating a true color icon does not use a common drawing approach, its code is as follows: Function Coalitionico (Var Ms: TmemoryStream): Boolean; Var M1, M2: TmemoryStream; Size: longint; fastue: dword; begin m1: = tmemorystream .Create; m2: = tmemorystream.create; size: = ms.size-14; ms.position: = 14; try m1.setsize (size); ms.read (m1.memory ^, size); m2.setsize Size-40); Fillchar (m2.memory ^, size-40, 0); m2.position: = 0; FVALUE: = iconhand [7] * 2; m1.seek (8, sofrombeginning); m1.write (Fvalue , 4); FVALUE: = m2.size * 2; m1.seek; m1.write (Fvalue, 4); m1.position: = 0; ms.setsize (0); ms.write (iconhand) , 22); ms.write (m1.memory ^, m1.size); ms.write (m2.memory ^, m2.size); result: = true; finally freeandnil (m1); freeandnil (m2); end; END; Complete source code, see attachment, which is accompanied by compiled EXE files and several demonstrations. The true color icon generated by this program is compatible with any Win32 development tool.

================================================= 补 补An additional approach is: Uses CommCtrl; Procedure Bitmaptoicon (Bitmap: Tbitmap; Iconwidth, Iconheight: Integer; IconFileName: String = '); // Preferably, the bitmap is first processed to the appropriate size and convert VAR. ImglistHandle: Thandle; N: Integer; icon: ticon; beginiff (Bitmap.width <> iconwidth) or (bitmap.height <> iconheight) Then Begin // Here you add some scaling the original graphic to the appropriate size. . (unfinished) end; ImgListHandle: = ImageList_Create (iconWidth, iconHeight, ILC_COLOR32,1,1); try n: = ImageList_Add (ImgListHandle, Bitmap.Handle, 0); IconHandle: = ImageList_GetIcon (ImgListHandle, n, ILD_NORMAL); ICONHANDE <> 0) and (iConFileName <> ') THEN BEGIN / / The output is the standard icon file saved if LowerCase (IconFileName, Length (iconfilename) -3, 4)) <>'. ICO ' then IconFileName: = IconFileName '. ico'; Icon: = TIcon.Create; Icon.Handle: = IconHandle; Icon.SaveToFile (IconFileName); Icon.Free; end; finally ImageList_Destroy (ImgListHandle); end; end; function using Export icon, must be DEL PHI hit the icon fix patch provided below. (3) Accessories (203 k)

转载请注明原文地址:https://www.9cbs.com/read-83605.html

New Post(0)