public static Icon Create(byte[] colors, int width, int height, PixelFormat format) { if (format != PixelFormat.Format32bppArgb) { throw new NotImplementedException(); } ICONIMAGE image = new ICONIMAGE(width, height, colors); ICONDIR dir = new ICONDIR( new ICONDIRENTRY[] { new ICONDIRENTRY(image, 0) }); dir.Entries[0].ImageOffset = dir.Size; Icon icon; binaryWriter.BaseStream.Position = 0; dir.Write(binaryWriter); image.Write(binaryWriter); binaryWriter.BaseStream.Position = 0; icon = new Icon(binaryWriter.BaseStream); return(icon); }
public unsafe MultiIcon Load(Stream stream) { stream.Position = 0; SingleIcon singleIcon = new SingleIcon("Untitled"); ICONDIR iconDir = new ICONDIR(stream); if (iconDir.idReserved != 0) { throw new InvalidMultiIconFileException(); } if (iconDir.idType != 1) { throw new InvalidMultiIconFileException(); } int entryOffset = sizeof(ICONDIR); // Add Icon Images one by one to the new entry created for (int i = 0; i < iconDir.idCount; i++) { stream.Seek(entryOffset, SeekOrigin.Begin); ICONDIRENTRY entry = new ICONDIRENTRY(stream); // If there is missing information in the header... lets try to calculate it entry = CheckAndRepairEntry(entry); stream.Seek(entry.dwImageOffset, SeekOrigin.Begin); singleIcon.Add(new IconImage(stream, (int)(stream.Length - stream.Position))); entryOffset += sizeof(ICONDIRENTRY); } return(new MultiIcon(singleIcon)); }
public unsafe MultiIcon Load(Stream stream) { stream.Position = 0; SingleIcon singleIcon = new SingleIcon("Untitled"); ICONDIR iconDir = new ICONDIR(stream); if (iconDir.idReserved != 0) throw new InvalidMultiIconFileException(); if (iconDir.idType != 1) throw new InvalidMultiIconFileException(); int entryOffset = sizeof(ICONDIR); // Add Icon Images one by one to the new entry created for(int i=0; i<iconDir.idCount; i++) { stream.Seek(entryOffset, SeekOrigin.Begin); ICONDIRENTRY entry = new ICONDIRENTRY(stream); // If there is missing information in the header... lets try to calculate it entry = CheckAndRepairEntry(entry); stream.Seek(entry.dwImageOffset, SeekOrigin.Begin); singleIcon.Add(new IconImage(stream, (int) (stream.Length - stream.Position))); entryOffset += sizeof(ICONDIRENTRY); } return new MultiIcon(singleIcon); }
public void Save(System.IO.Stream Stream) { _frames.SortAscending(); System.IO.BinaryWriter writer = new System.IO.BinaryWriter(Stream, System.Text.Encoding.UTF32); ushort FramesCount = Convert.ToUInt16(_frames.Count); ushort FileHeaderLength = 6; ushort FrameHeaderLength = 16; ICONDIR FileHeader = new ICONDIR(FramesCount); writer.Write(FileHeader.idReserved); writer.Write(FileHeader.idType); writer.Write(FileHeader.idCount); byte[][] data = new byte[FramesCount][]; foreach (BitmapFrame Frame in _frames) { int FrameIndex = _frames.IndexOf(Frame); if (Frame.PixelWidth == 256) { data[FrameIndex] = GetPNGData(Frame); } else { data[FrameIndex] = GetBMPData(Frame); } } uint FrameDataOffset = FileHeaderLength; FrameDataOffset += (uint)(FrameHeaderLength * FramesCount); foreach (BitmapFrame Frame in _frames) { int FrameIndex = _frames.IndexOf(Frame); if (FrameIndex > 0) { FrameDataOffset += Convert.ToUInt32(data[FrameIndex - 1].Length); } ICONDIRENTRY FrameHeader = new ICONDIRENTRY((ushort)Frame.PixelWidth, (ushort)Frame.PixelHeight, Convert.ToUInt16(Frame.Format.BitsPerPixel), Convert.ToUInt32(data[FrameIndex].Length), FrameDataOffset); writer.Write(FrameHeader.bWidth); writer.Write(FrameHeader.bHeight); writer.Write(FrameHeader.bColorCount); writer.Write(FrameHeader.bReserved); writer.Write(FrameHeader.wPlanes); writer.Write(FrameHeader.wBitCount); writer.Write(FrameHeader.dwBytesInRes); writer.Write(FrameHeader.dwImageOffset); } foreach (byte[] FrameData in data) { writer.Write(FrameData); } }
public unsafe static Cursor Create(ref CefCursorInfo cursorInfo) { CefSize size = cursorInfo.Size; if (size.Width > 0 && size.Height > 0 && cursorInfo.Buffer != IntPtr.Zero) { try { var bufferSize = size.Width * size.Height * 4; int ICON_HEADER_SIZE = sizeof(ICONDIR); var stream = new MemoryStream(); { DpiScale dpi = OffscreenGraphics.DpiScale; var source = BitmapSource.Create(size.Width, size.Height, dpi.PixelsPerInchX, dpi.PixelsPerInchY, PixelFormats.Bgra32, null, cursorInfo.Buffer, bufferSize, size.Width << 2); if (stream.Seek(ICON_HEADER_SIZE, SeekOrigin.Begin) != ICON_HEADER_SIZE) { stream.Seek(0, SeekOrigin.Begin); stream.Write(new byte[ICON_HEADER_SIZE], 0, ICON_HEADER_SIZE); } var png = new PngBitmapEncoder(); png.Frames.Add(BitmapFrame.Create(source)); png.Save(stream); stream.Seek(0, SeekOrigin.Begin); } CefPoint hotSpot = cursorInfo.Hotspot; var icon = new ICONDIR(); icon.IconType = 2; icon.ImagesCount = 1; icon.Width = (byte)size.Width; icon.Height = (byte)size.Height; icon.HotSpotX = (short)hotSpot.X; icon.HotSpotY = (short)hotSpot.Y; icon.BytesInRes = (int)stream.Length - ICON_HEADER_SIZE; icon.ImageOffset = ICON_HEADER_SIZE; using (var iconHead = new UnmanagedMemoryStream(icon._data, ICON_HEADER_SIZE)) { iconHead.CopyTo(stream); stream.Seek(0, SeekOrigin.Begin); } return(new Cursor(stream)); } catch (AccessViolationException) { throw; } catch { } } return(Cursors.Arrow); }
public bool IsRecognizedFormat(Stream stream) { stream.Position = 0; try { ICONDIR iconDir = new ICONDIR(stream); if (iconDir.idReserved != 0) return false; if (iconDir.idType != 1) return false; return true; } catch(Exception){} return false; }
public unsafe void Save(Stream stream) { ICONDIR iconDir = ICONDIR.Initalizated; iconDir.idCount = (ushort)this.IconImages.Count; iconDir.Write(stream); int entryPos = sizeof(ICONDIR); // Placeholder for an array if ICONDIRENTRY here int imagesPos = entryPos + iconDir.idCount * sizeof(ICONDIRENTRY); foreach (IconImage iconImage in this.IconImages) { // IconImage stream.Seek(imagesPos, SeekOrigin.Begin); // Header BITMAPINFOHEADER header = Make_BITMAPINFOHEADER(iconImage); header.Write(stream); // Palette - (none) // XOR Image stream.Write(iconImage.XOR, 0, iconImage.XOR.Length); // AND Image - (not needed) long bytesInRes = stream.Position - imagesPos; // IconDirHeader stream.Seek(entryPos, SeekOrigin.Begin); ICONDIRENTRY iconEntry = Make_ICONDIRENTRY(iconImage); stream.Seek(entryPos, SeekOrigin.Begin); iconEntry.dwImageOffset = (uint)imagesPos; iconEntry.dwBytesInRes = (uint)bytesInRes; iconEntry.Write(stream); entryPos += sizeof(ICONDIRENTRY); imagesPos += (int)bytesInRes; } }
public unsafe void Save(MultiIcon multiIcon, Stream stream) { if (multiIcon.SelectedIndex == -1) { return; } SingleIcon singleIcon = multiIcon[multiIcon.SelectedIndex]; // ICONDIR header ICONDIR iconDir = ICONDIR.Initalizated; iconDir.idCount = (ushort)singleIcon.Count; iconDir.Write(stream); // ICONENTRIES int entryPos = sizeof(ICONDIR); int imagesPos = sizeof(ICONDIR) + iconDir.idCount * sizeof(ICONDIRENTRY); foreach (IconImage iconImage in singleIcon) { // for some formats We don't know the size until we write, // so we have to write first the image then later the header // IconImage stream.Seek(imagesPos, SeekOrigin.Begin); iconImage.Write(stream); long bytesInRes = stream.Position - imagesPos; // IconDirHeader stream.Seek(entryPos, SeekOrigin.Begin); ICONDIRENTRY iconEntry = iconImage.ICONDIRENTRY; stream.Seek(entryPos, SeekOrigin.Begin); iconEntry.dwImageOffset = (uint)imagesPos; iconEntry.dwBytesInRes = (uint)bytesInRes; iconEntry.Write(stream); entryPos += sizeof(ICONDIRENTRY); imagesPos += (int)bytesInRes; } }
public bool IsRecognizedFormat(Stream stream) { stream.Position = 0; try { ICONDIR iconDir = new ICONDIR(stream); if (iconDir.idReserved != 0) { return(false); } if (iconDir.idType != 1) { return(false); } return(true); } catch (Exception) {} return(false); }
public static Icon Create(byte[] colors, int width, int height, PixelFormat format) { if (format != PixelFormat.Format32bppArgb) throw new NotImplementedException(); ICONIMAGE image = new ICONIMAGE(width, height, colors); ICONDIR dir = new ICONDIR( new ICONDIRENTRY[] { new ICONDIRENTRY(image, 0) } ); dir.Entries[0].ImageOffset = dir.Size; Icon icon; using (BinaryWriter bw = new BinaryWriter(new MemoryStream())) { dir.Write(bw); image.Write(bw); bw.BaseStream.Position = 0; icon = new Icon(bw.BaseStream); } return icon; }
private static Icon LoadIconFromResource(UIntPtr lpIconName) { HandleRef hmodule = new HandleRef(null, GetModuleHandle(null)); uint totalsize; RESOURCE_ICONDIRENTRY[] entries; SafeResourceBuffer[] entrybuffers; RESOURCE_ICONDIR dir; using (SafeResourceBuffer buffer = GetResourceBuffer(hmodule, lpIconName, MAKEINTRESOURCE(RT_GROUP_ICON))) { dir = buffer.Read <RESOURCE_ICONDIR>(0); if (dir.idReserved != 0 || dir.idType != IMAGE_ICON || dir.idCount == 0) { throw new InvalidDataException("There is no icon directory in resource data."); } entries = new RESOURCE_ICONDIRENTRY[dir.idCount]; entrybuffers = new SafeResourceBuffer[dir.idCount]; uint entrysize = (uint)Marshal.SizeOf(typeof(RESOURCE_ICONDIRENTRY)); ulong offset = (uint)Marshal.SizeOf(typeof(RESOURCE_ICONDIR)) - entrysize; totalsize = (uint)(Marshal.SizeOf(typeof(ICONDIR)) + (Marshal.SizeOf(typeof(ICONDIRENTRY)) * (dir.idCount - 1))); entries[0] = dir.idEntries; for (int i = 0; i < dir.idCount; i++, offset += entrysize) { if (i > 0) { entries[i] = buffer.Read <RESOURCE_ICONDIRENTRY>(offset); } uint iconsize = entries[i].dwBytesInRes; SafeResourceBuffer entrybuffer = GetResourceBuffer(hmodule, MAKEINTRESOURCE(entries[i].nID), MAKEINTRESOURCE(RT_ICON)); if (iconsize != entrybuffer.ByteLength) { throw new InvalidDataException("Reported resource size is not equal to the icon size."); } entrybuffers[i] = entrybuffer; totalsize += iconsize; } } using (SafeLocalAllocHandle iconbuffer = SafeLocalAlloc(LMEM_ZEROINIT | LMEM_FIXED, totalsize)) { using (UnmanagedMemoryStream outstream = iconbuffer.ToStream(FileAccess.ReadWrite)) { ICONDIR icondir = new ICONDIR(dir); iconbuffer.Write(0, icondir); uint iconoffset = icondir.idEntries.dwImageOffset; outstream.Position = iconoffset; uint entrysize = (uint)Marshal.SizeOf(typeof(ICONDIRENTRY)); ulong offset = (uint)Marshal.SizeOf(typeof(ICONDIR)); ICONDIRENTRY entry = icondir.idEntries; for (int i = 0; i < dir.idCount; i++, offset += entrysize) { if (i > 0) { entry = new ICONDIRENTRY(entries[i], iconoffset); iconbuffer.Write(offset, entry); } using (UnmanagedMemoryStream instream = entrybuffers[i].ToStream()) { instream.CopyTo(outstream); } if (outstream.Position != (iconoffset + entry.dwBytesInRes)) { throw new InvalidOperationException(); } iconoffset += entry.dwBytesInRes; } outstream.Position = 0; return(new Icon(outstream)); } } }
public static void ChangeIcon(string exeFilePath, string icoFilePath) { int len = Marshal.SizeOf(typeof(GRPICONDIR)); using (FileStream fs = new FileStream(icoFilePath, FileMode.Open, FileAccess.Read)) { // 读取图标目录 ICONDIR iconDir = fs.Read <ICONDIR>(); // 读取图标头列表 List <ICONDIRENTRY> iconDirEntrys = new List <ICONDIRENTRY>(); for (int i = 0; i < iconDir.idCount; i++) { ICONDIRENTRY iconDirEntry = fs.Read <ICONDIRENTRY>(); iconDirEntrys.Add(iconDirEntry); } // 读取图标数据列表 List <byte[]> iconDatas = new List <byte[]>(); for (int i = 0; i < iconDir.idCount; i++) { byte[] iconData = new byte[iconDirEntrys[i].dwBytesInRes]; fs.Seek(iconDirEntrys[i].dwImageOffset, SeekOrigin.Begin); fs.Read(iconData, 0, iconData.Length); iconDatas.Add(iconData); } // 生成GRPICONDIR GRPICONDIR grpIconDir = new GRPICONDIR(); grpIconDir.idCount = iconDir.idCount; grpIconDir.idReserved = 0; grpIconDir.idType = 1; // 1代表图标 // 生成List<GRPICONDIRENTRY> List <GRPICONDIRENTRY> grpIconDirEntrys = new List <GRPICONDIRENTRY>(); for (int i = 0; i < iconDirEntrys.Count; i++) { GRPICONDIRENTRY grpIconDirEntry = new GRPICONDIRENTRY(); grpIconDirEntry.CopyFrom(iconDirEntrys[i]); grpIconDirEntry.nID = (short)(i + 1); grpIconDirEntrys.Add(grpIconDirEntry); } List <byte> grpData = new List <byte>(); grpData.AddRange(grpIconDir.ToByteArray()); for (int i = 0; i < grpIconDirEntrys.Count; i++) { grpData.AddRange(grpIconDirEntrys[i].ToByteArray()); } IntPtr grpDataPtr = grpData.ToArray().ToPtr(); bool ret = false; IntPtr pUpdateRes = BeginUpdateResource(exeFilePath, false); for (int i = 0; i < grpIconDirEntrys.Count; i++) { // 更新图标数据 int id = grpIconDirEntrys[i].nID; ret = UpdateResource(pUpdateRes, new IntPtr((int)eResourceTypes.RT_ICON), new IntPtr(id), 0, iconDatas[i].ToPtr(), iconDatas[i].Length); } // 更新图标目录和图标头 // 32512为当前exe中Icon Group下id号 ret = UpdateResource(pUpdateRes, new IntPtr((int)eResourceTypes.RT_GROUP_ICON), new IntPtr(32512), 0, grpDataPtr, grpData.Count); ret = EndUpdateResource(pUpdateRes, false); } }
internal static string makeIconEx(string icon, int size, int depth, string icoFormat) { // Header of the whole file, the file may contain more than one Icon byte[] bytes = System.Convert.FromBase64String(icon); int colorsInPalette = depth > 8 ? 0 : 1 << depth; ICONDIR iconDir = ICONDIR.Initalizated; ICONDIRENTRY iconEntry = new ICONDIRENTRY(); BITMAPINFOHEADER bitMapHeader = new BITMAPINFOHEADER(); iconEntry.bWidth = (byte)size; iconEntry.bHeight = (byte)size; iconEntry.bColorCount = (byte)colorsInPalette; // 4 = 16 colors, 8 = 256 iconEntry.wBitCount = (ushort)depth; iconEntry.bReserved = 0; iconEntry.dwBytesInRes = (uint)(bytes.Length + Marshal.SizeOf(bitMapHeader) + colorsInPalette * 4); // Each color requires 4 bytes in the palette iconEntry.dwImageOffset = (uint)(Marshal.SizeOf(iconDir) + Marshal.SizeOf(iconEntry)); iconEntry.wPlanes = 1; bitMapHeader.biSize = (uint)Marshal.SizeOf(bitMapHeader); bitMapHeader.biWidth = (uint)size; bitMapHeader.biHeight = (uint)size * 2; bitMapHeader.biBitCount = (ushort)depth; bitMapHeader.biPlanes = 1; bitMapHeader.biCompression = IconImageFormat.BMP; bitMapHeader.biXPelsPerMeter = 0; bitMapHeader.biYPelsPerMeter = 0; bitMapHeader.biClrUsed = (uint)colorsInPalette; bitMapHeader.biClrImportant = 0; bitMapHeader.biSizeImage = (uint)bytes.Length; // // The icon is recieved flipped vertically, we need first to flip it before sending // it to the consumer // byte[] data = null; int len = 0, revIndex = 0, rowWidth = 0, ANDmapSize; len = bytes.Length; data = new byte[bytes.Length]; rowWidth = size * depth / 8; ANDmapSize = len - size * size * depth / 8; int step = 4; for (int k = len - rowWidth; k >= ANDmapSize; k -= rowWidth) { for (int r = 0; r < rowWidth; r++, revIndex++) { data[revIndex] = bytes[k + r]; } } for (int l = 0, m = ANDmapSize - step; l < ANDmapSize; l += step, m -= step) { for (int n = 0; n < step; n++, revIndex++) { data[revIndex] = bytes[m + n]; } } MemoryStream mStream = new MemoryStream(); // // Write the Icon directory // iconDir.Write(mStream); // // Write the icon directory entry // iconEntry.Write(mStream); // // Write the bitmap header // bitMapHeader.Write(mStream); // // Write the appropriate palette if required // if (depth == 4) { mStream.Write(palette_16, 0, palette_16.Length); } // // Write the icon data recieved from the CPS server // mStream.Write(data, 0, data.Length); byte[] outBytes; // // If the consumer requested an ico format return the stream as is without any conversion // if (icoFormat.ToLower() == "ico") { outBytes = mStream.GetBuffer(); mStream.Dispose(); return(Convert.ToBase64String(outBytes)); } // // Store the stream in an Icon object, this will solve the transparency problem // mStream.Position = 0; Icon iconStream = new Icon(mStream, depth, depth); // // Retrieve the icon as bitmap for conversion // Bitmap bitMap = iconStream.ToBitmap(); ImageFormat imgFormat = ImageFormat.Png; switch (icoFormat.ToLower()) { case "png": imgFormat = ImageFormat.Png; break; case "gif": imgFormat = ImageFormat.Gif; break; case "tiff": imgFormat = ImageFormat.Tiff; break; } // // Save the icon in the requested format to an icon to be sent to the consumer // MemoryStream oMStream = new MemoryStream(); bitMap.Save(oMStream, imgFormat); outBytes = oMStream.GetBuffer(); mStream.Dispose(); oMStream.Close(); oMStream.Dispose(); bitMap.Dispose(); // // Return the icon as base64 string // return(Convert.ToBase64String(outBytes)); }
// Layout: ICONDIR, ICONDIRENTRY[], PngData[] static void WriteIcoFile(string fileName, IEnumerable <Bitmap> smallerBmps, Bitmap big256PxSource) { var dir = new ICONDIR { reserved = 0, imageType = 1, numImages = (UInt16)(1 + smallerBmps.Count()) }; var entries = new ICONDIRENTRY[dir.numImages]; var pngsToWrite = new Queue <MemoryStream>(); // Smaller entries go first var i = 0; var offset = Marshal.SizeOf(dir) + (Marshal.SizeOf(entries[0]) * entries.Length); foreach (var img in smallerBmps) { entries[i].imageWidth = (byte)img.Size.Width; entries[i].imageHeight = (byte)img.Size.Height; entries[i].numColors = 0; entries[i].reserved = 0; entries[i].colorPlanes = 0; entries[i].bitsPerPixel = 32; var stream = new MemoryStream(); img.Save(stream, ImageFormat.Png); pngsToWrite.Enqueue(stream); entries[i].imageDataSize = (UInt32)stream.Length; entries[i].imageDataOffset = (UInt32)offset; Debug.WriteLine($"Storing {img.Size.Width}x{img.Size.Height} image with size {stream.Length} at offset {offset}"); offset += (int)stream.Length; i++; } // 256x256 goes last entries[i].imageWidth = (byte)big256PxSource.Size.Width; entries[i].imageHeight = (byte)big256PxSource.Size.Height; entries[i].numColors = 0; entries[i].reserved = 0; entries[i].colorPlanes = 0; entries[i].bitsPerPixel = 32; var bigImageStream = new MemoryStream(); big256PxSource.Save(bigImageStream, ImageFormat.Png); pngsToWrite.Enqueue(bigImageStream); entries[i].imageDataSize = (UInt32)bigImageStream.Length; entries[i].imageDataOffset = (UInt32)offset; Debug.WriteLine($"Storing {big256PxSource.Size.Width}x{big256PxSource.Size.Height} image with size {bigImageStream.Length} at offset {offset}"); offset = 0; // Write all of the data out to the ICO file using (var fileStream = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None)) { var header = GetBytesForStruct(dir); fileStream.Write(header, 0, header.Length); Debug.WriteLine($"Wrote header ({header.Length} bytes, offset = {offset})"); offset += header.Length; i = 0; foreach (var entry in entries) { var entryBytes = GetBytesForStruct(entry); fileStream.Write(entryBytes, 0, entryBytes.Length); Debug.WriteLine($"Wrote directory entry {i++} ({entryBytes.Length} bytes, offset = {offset})"); offset += entryBytes.Length; } while (pngsToWrite.Count > 0) { var pngStream = pngsToWrite.Dequeue(); pngStream.Position = 0; pngStream.CopyTo(fileStream); Debug.WriteLine($"Wrote PNG ({pngStream.Length} bytes, offset = {offset})"); offset += (int)pngStream.Length; } } }