Skip to content

Instantly share code, notes, and snippets.

@grassmunk
Last active April 16, 2020 20:17
Show Gist options
  • Save grassmunk/a8a2b9b4299c6f2a67674fb67c97829f to your computer and use it in GitHub Desktop.
Save grassmunk/a8a2b9b4299c6f2a67674fb67c97829f to your computer and use it in GitHub Desktop.
import sys
import os
import collections
import PIL.Image
import svgwrite
import pathlib
import shutil
import subprocess
import argparse
import logging
import logging.handlers
import configparser
import xml.etree.ElementTree as ET
from pathlib import Path
from PIL import Image
from configparser import ConfigParser
from fontTools import ttLib
#import binascii
import struct
from pprint import pprint
import json
# Python script to extract ICONDIR/IconDirectoryEntry and export all icons as single icon files
def extract_cur(file_name, dump=False, folder='./'):
# input: .cur file location/name
# output: dict with cursor information
f = open(file_name,'rb')
cur_file = f.read()
f.close()
cur_bytes = bytearray(cur_file)
rtIconDir = False
rtIconDirEntry = False
ICONS = []
idReserved = struct.unpack('<H',cur_bytes[0:2])[0]
idType = struct.unpack('<H',cur_bytes[2:4])[0]
idCount = struct.unpack('<H',cur_bytes[4:6])[0]
loc = 6
if idType == 1: # ICONS ONLY NO CURSORS
name = os.path.splitext(os.path.basename(file_name))[0]
for i in range(0,idCount):
#ICONDIRENTRY
# TODO Add multiple icons here if needed
rtIconDirEntry = {
'bWidth' : cur_bytes[loc], # Width, in pixels, of the image
'bHeight' : cur_bytes[loc+1], # Height, in pixels, of the image
'bColorCount' : cur_bytes[loc+2], # Number of colors in image (0 if >=8bpp)
'bReserved' : cur_bytes[loc+3], # Reserved
'wPlanes' : struct.unpack('<H',cur_bytes[loc+4:loc+6])[0], # Color Planes
'wBitCount' : struct.unpack('<H',cur_bytes[loc+6:loc+8])[0], # Bits per pixel
'dwBytesInRes' : struct.unpack('<L',cur_bytes[loc+8:loc+12])[0], # how many bytes in this resource?
'dwImageOffset' : struct.unpack('<L',cur_bytes[loc+12:loc+16])[0] # RT_ICON rnID
}
ICONHEADER = bytearray(2) + struct.pack('<H',1) + struct.pack('<H',1)
IconDirectoryEntry = cur_bytes[loc:loc+12] + struct.pack('<L', 22)
img = cur_bytes[rtIconDirEntry['dwImageOffset']:rtIconDirEntry['dwImageOffset']+rtIconDirEntry['dwBytesInRes']]
if rtIconDirEntry['bColorCount'] == 0: rtIconDirEntry['bColorCount'] = 256
filename = "{}_{}_{}x{}x{}.ico".format(name, i, rtIconDirEntry['bWidth'], rtIconDirEntry['bHeight'], rtIconDirEntry['bColorCount'])
if dump:
self.logger.info("Creating:", folder + filename)
f = open(folder + filename,"wb")
f.write(ICONHEADER+IconDirectoryEntry+img)
f.close()
ICONS.append({
'filename': filename,
'ID' : i,
'Width' : rtIconDirEntry['bWidth'],
'Height' : rtIconDirEntry['bHeight'],
'Colors' : rtIconDirEntry['bColorCount'],
'ICON': ICONHEADER+IconDirectoryEntry+img
})
loc += 16
return ICONS
print("Icon File: {}".format(sys.argv[1]))
extract_cur(sys.argv[1])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment