I have a program (in Pyglet) in which I would like to keep the icons of them in the form of bytes, then convert them into temporary images and pass them to the program to be able to use them.
This is a dictionary where the data of the two icons are present:
ico = {
"ico_16": {
"dimension": (16, 16),
"byte": b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04gAMA\x00\x00\xb1\x8f\x0b\xfca\x05\x00\x00\x00 cHRM\x00\x00z&\x00\x00\x80\x84\x00\x00\xfa\x00\x00\x00\x80\xe8\x00\x00u0\x00\x00\xea`\x00\x00:\x98\x00\x00\x17p\x9c\xbaQ<\x00\x00\x00\x06bKGD\x00\xff\x00\xff\x00\xff\xa0\xbd\xa7\x93\x00\x00\x00\x07tIME\x07\xe2\x08\x05\x12-\x0f?\xc1\x9b\xba\x00\x00\x03\x0fIDAT8\xcbU\x92Kh\\U\x00\x86\xbfs\xee\x99{g\xe6>f:\xe9<,3i51\xa6\x92B\xb5iHQ\n%.\n\xf6A)E(\xb5YtS\x8a R\\\xe8F\r\xe2^\x10WZ\x91\xae\x8a\x8b`\t\xbaP\xac\x0b\xad\x8a\xf4\x85\n\xadv\xa16\x19\'N\x9b\xcc+3\xb9\xcf\xe3b\xda\x85\xff\xf2\x87\xff\xdb\xfc\x9f`Q\xc31\x01\x07\xce\xc0\xee\xb9\x14?^~\x81^{\x9e`\xf3y\x92\xa4\x0c\x80\x94\xab\x98\xe9\xefpr\x9f2{\xe4kn~\x13r\xe5#X\xd4\x18L\x1f\x85\x9b\xdf\xc2\xe8\xce\n\xb7\xae\xbcK\xeb\xfe\x02A0\x8dP\x1e\x86)\x91J\x92h\x0f\x7f0E\xbf\xf3"\xcb\xb7+\x14*7\xe8\xb4{L\xeeC\x10h\x83\xb3\x1fV\xf9y\xe9\x036\xba\x87\xb0l\xc8\xb8`f\xc0H\x81\x90\x10\x87\x10\x0c\xa0\xdf\x01\xbf\x07\xb6\xbb\xc4\xdeC\xaf\xf0\xf1\xb9e\x83\xf1\xd7J\xf2\xea\xe2\x82\x8a\xa2\x97\x12\xd3\x037\x0fv\x0e\xbc"\xaa2\x0e\xb9\x1a\xda\x19\x01C\x82J\x81\xca\x92\xb22\x13\x84\xbe\xa7\x93}W\r\xd2\xe5\xe3\x8f\xef\xa8\xbe\xbe\xe7\xf8i\xab\xbe\x16\x10\xa1!\xe3\xa2JO\xb2\xff\xf0Q2\xa3\xbb\x99|z\x92\xd6\x86\x8f\xef\x87\xd8\xd5\xa78p\xfa\x0c~\xaf;\xde\xbe\xf5\xd3\x1dE\xfd\xce\x89\xcc\x13s\xae\xceo\xc7\xac\xcd\x90x\x7f#S\x06\xc2\xdeA*_\xc6\xf1$\xdb=\xe8\x0ff\xb8\xd6IHo{\x0c\x9d\xabaes.\xf5\x1b\'\x14\xfd\xf5imXh\x99\x86\xc2.\x9eyv\n\xcb\x92\\\xfb]\x90\x08\x89Pp\xbb\x03\xa9b\x8dL\xb5\x8bN\xbbh\x91F\x1bi\xe8\xb7\xf6*\xe2\xb0(\x0c\x05\x02\x84\x9dEf!2#:\x80\x04\x12\x88|h>P\xd4\xc6\xc6h\xb6\x14\x18\x02\x0c\x05IX\x94<\x8a\x00\x14h\xf9p\xa8\x1e\xf6\t\x88X\xd3\xb8\xf7\x00;k\xe0\x8cd\xd0\x02\x10b\xa8\x08\x86\xd9\xd4q\x08\x1a\x84\x1er\x1e\xf1\x10C\x00qH\xd4\xfe\x93\xc6\xf2\n\xd5\x92F\x03\xc41H\xb3)q\xb6^\x17I#\xab\xd1d\xe7\xd6\x01A\xbbM{u\x9d\xa9r\xc8z+\x81\x10d\x1c"7W\xf8\xe7\x8f_\x18\x89\xd6(Y#\x12\x83W\xba\xae\xe4\xcc\xc1\xcf\xad\x82\xbd\xff\xeeW\x9f9!\x12_\x18$R\x91\xcdo!\xb6\xca\xcc\xceN\x12\xf7\xd7\x88\xda\xf7\xa0\xdb\xe2\xb7\xef\rF\'\xc6P[\n=1}\xf0\xb2P_\xeaQyaa!\xf8\xf5\x87y,\x17\x9c\x1cX\x19H\xa5\xc1r1\xbd\x02\x89? Z\xaf\xc3\xa0\x0bA\x88\x88\x03\xd4\xd8\xae\x8b\xf1\xfc\x1bo\xa9\xa8B\x03\xa7\xf06J\x14\xe8\xd4\x0f\xe3w\x86*\xa7,P&\xc1\xfd\xbf \x89\xfe\xa7\xb2v\xf2K\xe1\xc8\xb6w(Q\x17\\X\x85W\xf7\xc0s\xc7*\xd4\xef\xbe\xc9F\xf7e4y\x0csx\x15#\x1cA\x1c\x80\xa0\x85\xed^\xa4:\xf1\x1e_\xbc\xdf\xe0\x93\x7f\x91\xe4K\xd0]\x86\xcd\x8d\x06s\xa7\xceS\xaa\x9e\xc4v/!\xf5\n\xb1\x1f\x11\xfb\x11R\xaf`\xbb\x97(UO2w\xea<\x9b\xfd\x06ZC\xae\xc8\x7f\xde\x160\x90\xb5\xbaI\xa8\x00\x00\x00%tEXtdate:create\x002018-08-05T18:45:15+00:00\xbf\xac\x1c\xb8\x00\x00\x00%tEXtdate:modify\x002018-08-05T18:45:15+00:00\xce\xf1\xa4\x04\x00\x00\x00\x00IEND\xaeB`\x82'
},
"ico_32": {
"dimension": (32, 32),
"byte": b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00 \x00\x00\x00 \x08\x06\x00\x00\x00szz\xf4\x00\x00\x00\x04gAMA\x00\x00\xb1\x8f\x0b\xfca\x05\x00\x00\x00 cHRM\x00\x00z&\x00\x00\x80\x84\x00\x00\xfa\x00\x00\x00\x80\xe8\x00\x00u0\x00\x00\xea`\x00\x00:\x98\x00\x00\x17p\x9c\xbaQ<\x00\x00\x00\x06bKGD\x00\xff\x00\xff\x00\xff\xa0\xbd\xa7\x93\x00\x00\x00\x07tIME\x07\xe2\x08\x05\x12+\x1a\x04F\xd8\xd7\x00\x00\x08\xc3IDATX\xc3\x9d\x97il\\\xd5\x15\xc7\x7f\xf7\xad\xb3\xd8c{<\xb6gL\xec\xd8\xb1]\xc7\xc4\x91\x1bB\x0c\x844II\xa9h\x8b(\x82\xb2\xb4H]>\xb0tQEAU#\xb4\xaa\xdb\xaa-\x15-\x82~#\x84(m?P\xf5C\x05\xdd\xa8\x8ah\xd9B\x81`\'\r\x11 \x12;\xc4\x89q\xf06\xf6,\x9ey\xb3\xbc\xad\x1f\xee\x9b\xd8NhUq\xa5\xa3;\xbao\xee9\xffs\xee\xb9\xe7\xfc\xaf\xe0\xc3\xc6]O#n\x01BQ\x98\x9d\x84\x07\x1fQ\xf8\xf1\x0f\xfa\xc9/\xee\xa1\xb4\xfcI*\xd6f\xecj\x12\xcf\x8d\x02\xa0\xa8Etc\x163\xf2\x16\xe1\xfa\x17\x895?\xcf\xf7\x7fx\x82\xfb\xee\xf6HvC\xb9\x08\r-\xf0\xf8\x1d\x17\x98\x12\x00<\xed\xaf\xac\xfc\xf9a8\xfd6\xc4S\xf0\x8b\x9f\x08\xbe\xb3w\x98\xcc\xecW\xc9/^C1\xdfA\xb5\xac\xe2\xb9\xe0\xafl\x07_\xfeTT0B.\xd1\xd8\xfb\xc4\x9a\x9f\xa5)\xf9[\x1e\xfe\xf9(\xdf}\xc0gi\x06\xba\x06\xe1\xf3\xf7\xac\xd8\xbaA \xd6\x18\x0f\x033s\xf0\xfb\x11H\xacK1s\xean\x16\xcf~\x8d\xfcR\x0b\x8e\x03\x8a\x06\xaa.gEY\x0b\xc0\xf3\xc0s\xc0\xb5\xe5\xaci\x10\x8b\xa7i\xbe\xe8\xd7\xa46<Bzz\x86/\x8e#\xaa\rJ\xab#p\x0e\x80/\x88\x08\xb8F\xf8\\\x7f\xff6fN\xfe\x92\x85\xe9OP)\x83f\x80\x16\x02M\x07E\x97\x9e~(\x00W\x1aw\xaa\xe0T\xa4\x98!hY\xf7/R\xbd\xf7\xf0\xa7\x9f\x8d\xf1\xac/\xb0|#\xf8\x00*\xb7\x8c\x08#\x05\xa1p-\n\xef\x88=\x9cy\xfb\x00sS[p=0\xeb\xc0\x8c\x82\x19\x01#\x0cF\x08\xcc0\xe8!0L9\xebf\x00\xd2\x005\x88\x92\xaaI\xa0v\x05\n\xd9N\x9c\xean\xae\xbc\xf58\xf7\xef>\xc3qq\x0e\xbd\xca-#\x1a\xbe\xaf\xd3)4F\xf6og\xfc\x8d},L\xf5\xa2\xe8\x10\xaa\x97\x89hD\x02\xc3\xa1\x15\x10F8X\x0f\xc0\xe8\x86\x8c\x90\xaa\xcb\xf0+jpT\x9a\x8c\x8c\x95k\xc6u\xb63\x96=\xc6U[g\xc9\xf9\nB\xa0r\xcb\x88IT\x98\xbc:\xd6\xcb\xd8\xdf\x1e\xe5\x83\x93\x9bQL\x087\x04\xdeG\xa4\xa7Fh\xc5{#\x1aD\xa5\x1e\x8c:\tD\x0f\x05\x9e\xabR\x94#\xd4\xe0\xd8<\x0f\x8a\xd98\xae;\x80h}\x8d\xaeu\xcb\xd8\xf8\x1a\x02\x83\n1\x8e\xbe\xf0\rr\xe9aR\x1b\xc1\x13\xe0:\xa0\xa9\xa0)\xa0*R\xa9f\x80\x16\x06=\x02\xe18\xd4\'\xc0\x15\xc8<\x11`[\xb0<\x07\xd5\x02he\xd0L\xd0\x1d)\r\xed \x1c\xc8.\x0cs\xf4\x85o\xb2i\xf8G\x08\xf2*w\x8e\xd4\xf3\xf2s;\x18\x1f\xdb\xdb\xbb\xfb\xd3\xe1\x9bn\xbf\x03\xadc#gg\xb32\xbf\x0c]\x86V\x0b\xce\xdb\xac\x87\xba6\xba\x87\xaf\xe4\xa6\xcf\\F\xa8\xad\x93\xf7\x97\xe3t\x0en\xa4\xf3c\xeb\x99\x9f\xcb\xcaDTT\xe9\xb9\x1aB$\xba\xd8\xf5\xa5\xdb\xb8\xe6\x86\xebIW\x15r\x13\xefl\x00\xed\xdf\x0c\xf6N)\x14\x882~\xf8\x0bxn\xd3\xce\xdd\xbb\x98v\xa2\x0c\r\r\x10\xe9\xda\x0c\xd1\x16\x087\xc9\\\xa8\x85\xdcl\x84\xc6\x0evm\xe9\xe1\xac\x1b\xe5\xd2\xdef"\x9d}\xacO\xa5\xb8{\xe7z\xa2]\x9b \x9c\x80P\x83<\xc6H3\xb1\x9eA.\x1d\xeag\xda\x8d\xb2m\xe7N\xb0+ML\x1c\xb9\x89e\xa2\nG^\xe9c~r\x07\xa8(\x9a\xc1\xf8\x07\x16%\x1b\xb4\xfa$D\xdb\x03eq0\x9b \xd4\x0c\xe1\x16\x88\xa4\xd0T\x83\x89\x0cT=0\x1a\x15\x1c]\xb0)\xaer\xd9P\x0f\xc4:\xe4\x9eP\x13D\x12\xe8u\t\x8a\x15\x9f\xe3\xd3E\x14=\x04B\x83\xf9\xc9\x1d\x1c~\xb9Oc\xf2\xd8v\x96\xd3I\x12\xbd\xf8BEQM\x84\xd0!\x94\x84\xba\x12(\x05"\xcd\x11tC#\xb7X\x02\xaf\x0e\xcc\x14\xbe\xa2!T\x10\x02\x08\x81\xad\xc1\x81S\xd0\xdb\xd1\xc8hG7\x85I\x1b\xec"`\xe2\x1b1\x84PQ\xb40\x08\x0b\xf40d\xcf$\x99<v\xa5\xc6\xd2\xf4\xe5TK*z\x18\x84\x02\xaa)g\xb3\x15\xa2\x1a\xb1\xa4\xc7\x97\xafj!l\xaa<5\x96\xe1\xd4\xb8\x07f<(\xbd\xf26\x0bMV\x92\x93Y\xd0\x84\xc2%\x17\xb7sp!\x0fVF\xa2\xd3cR\xa7b\x82(\xcb$\xae\x96T\x96\xce^\xa1P\xcc\xf4\xe3{2\xc3\x85\xe0\x9c[\x86\x01\xe1VR\xedI,_\xe7\xd0\xac\xc2\x86T\\\x1e\x89\xae\xae\xee$\xe7\x86\xe2\xc2\x1b\x93\xd0\x9b\x8aR\x97J\x81\xd9,E\xab\x0f\x00hr\xd6\x0c\xf0=\xb02\xfd\nU\xab-\xe8h\x81\xd2#\xab\x06\x84\x14\x84\xaePq\xc0\xb2\x01U\x80)\xe4\xb7\xd5\xc6]\xc0\x93K\xf94Le\x14\xb6\xf4\x07\xf9b\xb4\x80\x16\tt+R\x7f\xcdV\xd5jS\xf0\x9c0\x8a\x90\xb5]\x08\xa9\xa5\x16^mU\x98k\xc5\xb3\xb6\xb6zx\x81\xf8#\xd9\xe7\xc8\x84M_\xd2\xa4\xae-\x01F\x93\x8c\x98X\x05\xbaf\xcbs\xc2\xe7\xabZ\x15Oy\xae5\x00k\x80}\x18\x00?\x98\xed\n\x99\x99,S\x8b6[\xfa"\x10\xd2\x11\xea\x9a\xe6\x7f\x9e\x19E+\xe1\x05\xdd\xcc\xf7\xd7~=\x7f\xc3j\x00\xab=\xaaE\xc0\xf3\xc1\xceA)\xcd\x91\x139\xfaZ}\xa2\t\xf0\x95\xf3ty\xbe\xb4\xa5h%\x05#2/\x17\x9ds\x9du\x8d\xfc?\xa3\x16\x01\xdf\x01\'\x0b\xf6\x12\x99\x0f\xe6\x99J\x97\xd9\xd2\x05\x9e\xbaJ\x97\x8flN\x00FdN\xa1.~\x02\xa1\x80c\x83\xef\xe1{\xdeJbUV\x94\xfb5#\x8e\xfc&\x08\xd6\xd6\x80v\xc0\xc9\xcb(\x14\x178\xfcn\x9a\x9e\xb8O\xac>\xb0_\x03\xe1\xba\xf2\xeeF\x9bO($\xd6\x8fbD\\\xec\x12\xf8\x1ev\xa1\x80U\xb2\x19h\x87h#\x0c\xb6\xc2|\xceg~\xd1\xa3\xb3\x01\xe2M\xd0\x11\x97y\x95-\x04\xb4\xc2\xa9\x01u\xc0Y\x96 \xcai\xb2g\xa685[\xe0\xf2\x0e\xd9\xab\xe4\x7f<\xb0\xcb`F\\\x12\x9d\xa3\x1a=\x97\x1c\xe2\xe4\x9bs\xd8V;x\xf8\xd9\x19^|\xd5\xe3s\xbb\xba\xd8\xb6Ng!_\xe6\xb5#\x0bXE\x97\x93u\tn\x1d\xaa\xc7\xf5\xe1\x95q\x9flZE\xf4\x08\xbc\x8a\xb4\x8df\x83\xbd\x0c\x95\xbc<c\xc7\xe1\xe8\xb1\x06n\x1b\xbc\x18\xdf\x15\xfc\xdd\xb6\xf1=\x07\xec\x12\xc4\xda\xe6\xe8\xdd\xfa\x86\xc6\xa6\xe1I\xde\x1d}\xbd\xb1\xce\xb8\xb1\xa9>\x82\x9d9\xca\xe2\xb1\t~w&\x89\xd9\x10\xa5T,\xe1\x97\xcb \x04\x07\x9f\x8b0\xda\xd4\x88\'L\xaa\x96\x89\xda\xd4\x86\xe2\'\xe9N\xf8t4\t2\x8be\xa8\xe4\xa0\xba\x1c\xe4\x94E\xe1$<\xf7v3\x9f\xda\xd8B\xb5\xb8#cW=u\x03\x9b)\x94\xbdC\x0c\x0eOj\x18Xl\xbd\xfa\xaf=\xc9\xd0\xd5o\xbd;\x11\x9b}\xf3 d\xb2\xb8\xd6\x14\x96a\x80\xaeI\x86\xa3\xaaPT)/\xe9\x01?\xac\xc3\xad\xcc\xf2\xca;6W\xf4\'\xc8Y6/\xbd5\x0eVZ\x02pl\x19\xf2b\x9e\x7f\xbc`\xb2`}\x9c\xb9#\xafs\\\xdd\xc8E\xdb\xf7\xe4Od\xbcg\xd0\xb1\x04O\xfbI4\x1a\xc4\xf3\x7f\xb8\xdf?\xf4\x97\xaf\xb04+\xdbn(\x1ap\xbe\x80\xeb\xd5#(\x01\xedRMINB1D$\x8a_-C~\x01\xcaYIL\x9c*8.8\x9e\xac^\x9a\x0e\x8bS\x10\xad\x87\xcb\xaf{\x92=7<\x88\xc3\xa2\x06\x94Qq\xfd\xd6\xf5\xbf"\x14\x1e\xc0)\x0e\xe3\x96\xc1-\x81\x1d\x96 43\xe0{j#:\xb5\x80\x1d\xeb`\xa5\xf1\x17\x05\xf8\xae\xa4\xe4NY\x12Q\xa7\nvM*P.\xc8\xeb\xd3v\xd1a:\xfa\x1fCa\x11(k#\x85\n\x0e\xbb\x87\'\x98<z\x1fV\xe6\t\xe6N\xf7\xe2:\xe0V\xc1\tI&\xa4\x05\xccHY\xc5\xf9\x84\xbaR\xa3k\xef\x02\xa7*\xf7\xd5\x0c\xdbe\xa8X2K\x93\x1b\xdec\xe0\xb2\x07\xd8\xba\xe98\x19\\d\x17\xa7\n(\xcc!\xd8\x7f\xe7An\x9c\xfe:\x9e\xfd\x18\x0b\xd3}\x94\xf2\xd2+\xd7\x96Q\xa8\x91\xce\x1a\xe1\x14A9\xf4\x83\xca\xe6\xd5\xa2`\xcb7\x81]\x86jI\xde\xd5\xd6\x8e\t\xd6o\xfa\x16\xf7\xde\xf6\x12G\xa9]JO\xf0\xb4\xbfR$#\xc0g\xa3>\xd7}{\x1b3\xef=\xcc\xc2\xf4\x0eI8W\x1d\xc3G}\x98\xb4\xf7\xdd\xcb\x1f\x7f:\xca3\xbe\xa0z\xce\xa2\xaf\\P|\xf7\x9d\x80Bv\x8c\xee\xa1\x9b\xe9\x1cx\x88xk\x1a\\(\xe7\xc1\xcaA)\x07\xa5\xfc\x7f\x91\x1cXY\xf9_\\\x88\xb7\xa6\xe9\x1cx\x88\xee\xa1\x9b),\x8d\xf2\x9b9\x10k\x0b\xfd\xda\xbef\x01\xaf=U;\xb7\x19\xf6\x1f\xd8K\xf7\xd0\xb5t\x0e\xec#\xd1~\x1a3\xe4\xe2\xd9\x92v\x9fo\xbcZ\x00\xcf\x063\xe4\x92h?M\xe7\xc0>\xba\x87\xae\xe5\x89\x03{\xa9X3TJ\xf0\xe4\xf7dy\xff\x1f\xfdN\x8e\xbb\xf6Cn\xfe\xa3>\xcf_"\xd6\xfc\xcf\x0b\x9f\xe7\xad\xf0\xf8\xed\x17\x98\xfa\x0f\x10\x99\xc4\xde3\xad\xf4\x83\x00\x00\x00%tEXtdate:create\x002018-08-05T18:43:26+00:00\r\xd5q\x81\x00\x00\x00%tEXtdate:modify\x002018-08-05T18:43:26+00:00|\x88\xc9=\x00\x00\x00\x00IEND\xaeB`\x82'
}
}
While this is the part of the script in which it is converted into temporary images and passed to Pyglet:
temp_ico = []
for ic, ic_key in ico.items():
with BytesIO() as ic_key["byte"]:
from PIL import Image
with Image.new("RGB", ic_key["dimension"]) as ico_img:
ico_img.save(ic_key["byte"], format="PNG")
ico_img = pyglet.image.load(ico_img)
temp_ico.append(ico_img)
self.set_icon(temp_ico[0], temp_ico[1])
The problem I'm having is that Pyglet, with: pyglet.image.load(), expects the file path and not the file itself.
Since the file is not physical, I do not know how to get the path of it to get it used by Pyglet. Do you have any suggestions or advice on how to solve the problem?
Edit:
I tried with both answers obtained from "Torxed":
temp_ico = []
self.temp_sp = []
for ic, ic_key in ico.items():
ico_img = pyglet.image.ImageData(ic_key["dimension"][0], ic_key["dimension"][1], 'RGB', ic_key["byte"])
temp_ico.append(ico_img)
temp = pyglet.sprite.Sprite(ico_img)
temp.x = randint(0, 100)
temp.y = randint(0, 100)
self.temp_sp.append(temp)
self.set_icon(temp_ico[0], temp_ico[1])
And:
temp_ico = []
self.temp_sp = []
for ic, ic_key in ico.items():
ico_img = pyglet.image.SolidColorImagePattern((255, 255, 255, 255)).create_image(ic_key["dimension"][0], ic_key["dimension"][1])
ico_img.set_data('RGB', ico_img.width * len('RGB'), ic_key["byte"])
temp_ico.append(ico_img)
temp = pyglet.sprite.Sprite(ico_img)
temp.x = randint(0, 100)
temp.y = randint(0, 100)
self.temp_sp.append(temp)
self.set_icon(temp_ico[0], temp_ico[1])
But in both methods I get a mix of confusing pixels and not the original image.
I have also modified the method in which I obtained the printing of the image bytes. Before I used this method:
from io import BytesIO
from PIL import Image
with BytesIO() as output:
from PIL import Image
with Image.open("ico_32.png") as img:
img.convert('RGB').save(output, "png")
data = output.getvalue()
print(data)
Which I had obtained from here Answer by: perillaseed
But then I changed to:
s = open("ico_32.png", "rb")
data = s.read()
print(data)
s.close()
f = open('new_image.png', 'wb')
f.write(data)
f.close()
If I go to check the new saved image, it is exactly the same as the original, so I copy the byte string manually, insert it in the dictionary and it does not work.
Here are the visual results:
Also, I wanted to warn that I put the two icons as sprite and designed to see them better, since they were too small on the actual icon of the program.
To respond to snakecharmerb, I tried when you answered the suggestion you gave me, but as he also answered Torxed, I get the error he reported himself.
Edit2:
I tried to change the icons (since the two I used were only for testing and not the final ones of the program) with two others, but I get the same result. Above are the original ones, under the new ones.
Bytes string (new_ico_16):
b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x03\x00\x00\x00(-\x0fS\x00\x00\x00\x03sBIT\x08\x08\x08\xdb\xe1O\xe0\x00\x00\x00\tpHYs\x00\x00\x01\xc1\x00\x00\x01\xc1\x01E\x85\\9\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\x9b\xee<\x1a\x00\x00\x00\xd2PLTE\xff\xff\xff\x00\x00\x00O33gNNm/1l/1t./\x87`cy*-\x86_b\x8f*+\x8efiz,/\x90hl\x94!$\xa1\'(\xa3{|\x8eln\xb4$&\xb9 !\xa1\x88\x8b\x8b"#\xae\x8f\x91\xbc\xa8\xaa\xbe\xb0\xb2\xe4\x19\x1a\xec\x1d\x1d\x90\x8d\x90\x85\x88\x8c\x89\x8b\x8e\x8b\x92\x96\x90\x95\x98\x96\x9e\xa2\x97\x9f\xa3\xa2or\xa4`b\xa9\x19\x1a\xaa\x1b\x1d\xaa\xb5\xba\xaa\xb6\xbb\xab\xb2\xb7\xab\xb3\xb8\xab\xb4\xb8\xab\xba\xc0\xb7\x11\x12\xb9\xc4\xc9\xbe\xc0\xc2\xbf\xbb\xbc\xc4\x14\x15\xd0\xde\xe3\xd6\t\t\xd8\n\n\xd8\xe5\xea\xda\n\n\xda\x0b\x0b\xda\xe6\xeb\xdb\xe7\xec\xdc\xe8\xec\xe0\r\r\xe1\r\r\xe2\xec\xef\xe2\xec\xf0\xe4\xe5\xe6\xe7\x10\x10\xe8\xf0\xf3\xec\xea\xeb\xf4\x16\x16\xf5\xf8\xfa\xff\x1a\x1a\xff\xff\xff\xeb\x12-N\x00\x00\x00\x1ctRNS\x00\x01-4\x81\x82\x91\x9d\x9e\x9e\xb0\xb2\xb8\xc1\xd0\xd1\xd8\xd9\xe5\xe9\xf1\xf2\xf2\xfb\xfc\xfd\xfd\xfe(\xffw\x99\x00\x00\x00\xb0IDAT\x18\x19=\xc1\x89\x1a\x81#\x14\x06\xd0\x7f\n\x955Id\xdf\xf7\xc24\xd6\x90\xf5\xfd_\xc9\x1d\xfa:\x07\x92\x92\xc9\x96J\xd9\x8c\x82?\x96\xb6\xde?V\x9a\x81\xb0|\xe3\x19\x85\xfb}\x18=\x1by\x06 \xe5\x9ey\xec\xec\xa6\x00\xa5\x12\xf0DPQ\xa0\xef\xb8\xb4\xd9pi\xa7\xa3\xc8\xa5\xc1l6\xe4R\x11\xd5\x15\x19\xcf\xbb\x9d\xf5hE\xaahzd\xbah\xb7\xfc\x89G\x9a\xb0\x85\xd4\xf7\xfd\x9e\x90l\x14\x8e\x82l\x97\xcb\xad \xc7\x02\xd4\xfaA$\x0eu\x15\xd0n\x17\x11\xbb\xdc4\x00\xac\xfcx\xdd\xaf\xa7\xd3\xf5\xfez\x94\x19\x083j\x9f\x9f\x9a\xc1\xf0\xa7\xe6L\xc71s*\xc8\x17B\xf5#3;\xd8r\xdc\x00\x00\x00\x00IEND\xaeB`\x82'
Bytes string (new_ico_32):
b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00 \x00\x00\x00 \x08\x03\x00\x00\x00D\xa4\x8a\xc6\x00\x00\x00\x03sBIT\x08\x08\x08\xdb\xe1O\xe0\x00\x00\x00\tpHYs\x00\x00\x03\x82\x00\x00\x03\x82\x01\x83\x06\xfdz\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\x9b\xee<\x1a\x00\x00\x01\xb3PLTE\xff\xff\xff+++$$I77739944;77;F47UFIJ36K27M27ZIL[JM[JNG37J37SGKN26L26J36N14T15UIMU25P16U15O26Q/2YLPWLOUJNYMQ\x8f)+^RUXORYOS^SV_TWK15\xaa&\'\xae%\'\x89%\'YRV\xc9\x1f \xd5 !\xd7\x1f NMQ\x95\x8c\x8e\xad\xa8\xa9\xb2\xac\xae\xc5"#V\\`Z_d^?B_KOj8;kptnDGnruotxpy~qtxtvy\x81\x88\x8c\x82\x89\x8d\x82\x90\x96\x83?A\x8a\x91\x95\x8a\x92\x96\x8c\x8b\x8e\x8d\x90\x93\x91\x92\x94\x93\x96\x98\x95\x8f\x91\x99\x1a\x1b\x9a\xa3\xa8\x9c\xa7\xac\x9d\xa9\xad\xa2\x18\x19\xa3\x18\x1a\xa8\xb7\xbd\xb1\xc3\xc9\xb2\xbd\xc2\xb4\xbf\xc3\xb6\xc1\xc6\xb8\x14\x15\xb8\xc3\xc8\xba\xc3\xc8\xbb\xcc\xd2\xc1\x0f\x0f\xc5\xc5\xc6\xc7\xd6\xdc\xc8\xce\xd0\xc9\xca\xcb\xce\x0b\x0b\xd0\xd0\xd1\xd0\xdd\xe2\xd4\n\n\xd4\xe1\xe6\xd5\t\t\xd5 !\xd5\xd4\xd4\xd5\xd5\xd6\xd5\xd6\xd7\xd5\xe2\xe7\xd6\t\t\xd7\xd6\xd7\xd7\xd8\xd8\xd8\xe5\xea\xd9\n\n\xda\x0b\x0b\xdb\xe7\xec\xdc\xe8\xec\xde\x0c\x0c\xdf\r\r\xdf\xea\xee\xe0\r\r\xe1\r\r\xe1\xeb\xef\xe2\xec\xef\xe2\xec\xf0\xe7\x10\x10\xe8\xf0\xf3\xe9\x1d\x1d\xe9\xea\xea\xeb\xf2\xf4\xed\x13\x13\xee\xf4\xf6\xf3\x15\x15\xf3\xf7\xf9\xf4\x15\x15\xf4\x16\x16\xf4\xf8\xf9\xf5\xf8\xf9\xf6\x17\x17\xf6\xf9\xf9\xfa\x18\x18\xfa\xfc\xfc\xfc\x1a\x1b\xfc\xfc\xfc\xfe\x1a\x1a\xfe\xfe\xfe\xff\x1a\x1a\xff\xff\xff0\xafA\xf0\x00\x00\x004tRNS\x00\x06\x07\x17-JJ\x8a\x96\xa9\xad\xad\xb9\xbe\xbe\xd0\xd7\xde\xdf\xe0\xe2\xe2\xe4\xe6\xe7\xe8\xe8\xe9\xee\xee\xef\xf0\xf2\xf2\xf4\xf6\xf6\xf6\xf6\xf7\xf7\xf7\xf8\xfa\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xce2\x02\x1d\x00\x00\x01\xe4IDAT\x18\x19u\xc1\x07[RQ\x18\x00\xe0\xef\xde\xc3T\x14q\xef\xbd\xf7\xa0\xc8\xcar\x90JZ\xa2\xe2^X\xa8p\xec\x88\x88\x8a{/p\x9c\xef\'\x87>r\xb8(\xbc/D\xc9\xea\xa4\xb4\xf4\xec\xec\xf4\xb4$\xb5\x0c\xef\x11}^\xd9\xca=\x0f\xbb_)\xcb\xd3\x13\x88%is;\xb8BG\xaeV\x02\x05b\xac{\xe41\x1e\xeb\x8c\x04\x04UF3\xe7<xyz\xb0\xeb\xf5\xee\x1e\x9c^\x069\xe7\xcd\x19*xE2\x8f8?\xdf\xa2\n[\xe7\x9c\x1fe\x12x!\x19\x9b\xf8\x95\x9f\xbe\xe1\xbf\xe2MF\t\x9eik\x83;4\x8e\x9d`\xad\x16\xc2H\xfe\xad\x97\xc6\xe5\xbd\xcd\'\x00\xa0o\xdc\xa0\tl4\xea\x01\xe4\x02?M\xc8_ \x83\xba\x9eF\xb9\xec}}v\x17\x8d\xaaWC\xf2$\x15f-V\x87\xc3j\x99\xa5\xc2d2d-\xd1\x08\x97e\x8a\x8d\x8f\xb3\x85\x8f\x7fh\xc4R\x16\x14R\xc1ne\x9d\xdd\xdd_\xf0\xe7\x08\x15\n\xa1fH\xf8\xec\x98\x188a=n\xe7\xa7!\xa1\x06Z\x86\x85\xaf\x8e\x89\x01<\xe9q;;\x87\x85\x16h`\xc2\xef\x1f\xec\xdb\xe0\xe0w\xb4\xfdbB\x03\x94.\xb3\x08\xcf\x87\x05t\xbb\xf1\x9f\xf9/\x8bX.\x85\xd4i&\x8c\x9amN\xa7\xcd<\xca\x84\xe9T\xd0\xf43\xc13\xd6\xdb\xd5\xd5;\xe6aB\xbf\x06\xe4\x8a\x00\x8b\x9a\x9f\x99\x99gQ\x81\n\x19\xc0\xb0\xb8\xc9\x12\xd8\\4\x00\x00\xa9\xba\xf3\xb1\xb8|wU\x04\xc2tm\xa1=\x16\xc7^\xa8M\x07\xcf$\xd3*\xde\x04\xd8\x1b\x81\x1b\\5I\xf0\x82\x94\x1c#^l3\x85\xed\x0b\xc4\xe3\x12\x02\xafT\xc5\xeb\x88\x18\xba>;\xdc\xf7\xf9\xf6\x0f\xcf\xaeC\x88\xb8^\xac\x02\x81\x98\xda\x9f0\xc6S\xbb\x89\x80\x82\xa4\xab\x9eC\x85\xb9j\x9d\x04\xb1\x88\xa1\xb2u\xed\x01\xc3\x1e\xd6Z+\r\x04\xde\x935)9E\xe5\xe5E9)\x1a\x19\x84\xff\xe6\x8b7\xda7\x9aJ\x93\x00\x00\x00\x00IEND\xaeB`\x82'
I also tested this way (by modifying the script in the first edit), but with no different results from before:
s = open(ic + ".png", "rb")
data = s.read()
ico_img = pyglet.image.SolidColorImagePattern((255, 255, 255, 255)).create_image(ic_key["dimension"][0], ic_key["dimension"][1])
ico_img.set_data('RGBA', ico_img.width * len('RGBA'), data)
s.close()
What #snakecharmerb said is completely true, you could load it via a BytesIO stream. And it's usually the way most people go. The problem with it is that you need the complete data in order for it to load, otherwise you'll get:
Traceback (most recent call last):
File "test.py", line 19, in <module>
kitten = pyglet.image.load('kitten.png', file=kitten_stream)
File "C:\Program Files\Python37\lib\site-packages\pyglet\image\__init__.py", line 205, in load
raise first_exception
File "C:\Program Files\Python37\lib\site-packages\pyglet\image\__init__.py", line 195, in load
image = decoder.decode(file, filename)
File "C:\Program Files\Python37\lib\site-packages\pyglet\image\codecs\gdiplus.py", line 283, in decode
bitmap = self._load_bitmap(file, filename)
File "C:\Program Files\Python37\lib\site-packages\pyglet\image\codecs\gdiplus.py", line 226, in _load_bitmap
'GDI+ cannot load %r' % (filename or file))
pyglet.image.codecs.ImageDecodeException: GDI+ cannot load 'kitten.png'
To get around this, you can create your own valid image structure and in-line replace the data.
And I like quirky solution, so I'll drop this little nugget for anyone who needs to manipulate data/pixels in a way you're planning on doing.
ico_img = pyglet.image.SolidColorImagePattern((255,255,255,255)).create_image(16, 16) # Width, Height
ico_img.set_data('RGB', image_data.width*len('RGB'), ico['ico_16']['byte'])
What this does, is basically just crate (pretty quickly) a solid image blob with the right format. Then it in-line replaces the data with whatever you give it. The only important thing here is that your width and height matches the data-length/format chosen. I assumed the data you've got going is RGB and it appears to be working.
Now, I recon this is the fastest way to do it.
But there's a better and almost as fast way of doing it, and it's more readable:
ico_img = pyglet.image.ImageData(16, 16, 'RGB', ico['ico_16']['byte'])
This accepts any data stream that's valid RGB data (0-255).
Lastly, don't forget to place your image in a sprite object to make it faster and easier to work with:
ico_img_sprite = pyglet.sprite.Sprite(ico_img)
It'll make your life easier in the long run! :)
Edit: there are three differences in the first post and the methods to solve this.
Firstly, the original image data appears to be broken, so it's hard/impossible to load.
Secondly, seeing as the new raw data contains meta-data such as headers, creation timestamp etc. It will only be loadable via the io.BytesIO method, because it needs to go through any available image decoder.
Thirdly, you need to extract the image data (pixel-data) from the image in order to use any methods posted in my answer. Since it will bypass any image encoders and/or compressions. Making it a little bit faster, but at the expense of image data size.
Here is snakes answer working with the new data:
raw_image = b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x03\x00\x00\x00(-\x0fS\x00\x00\x00\x03sBIT\x08\x08\x08\xdb\xe1O\xe0\x00\x00\x00\tpHYs\x00\x00\x01\xc1\x00\x00\x01\xc1\x01E\x85\\9\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\x9b\xee<\x1a\x00\x00\x00\xd2PLTE\xff\xff\xff\x00\x00\x00O33gNNm/1l/1t./\x87`cy*-\x86_b\x8f*+\x8efiz,/\x90hl\x94!$\xa1\'(\xa3{|\x8eln\xb4$&\xb9 !\xa1\x88\x8b\x8b"#\xae\x8f\x91\xbc\xa8\xaa\xbe\xb0\xb2\xe4\x19\x1a\xec\x1d\x1d\x90\x8d\x90\x85\x88\x8c\x89\x8b\x8e\x8b\x92\x96\x90\x95\x98\x96\x9e\xa2\x97\x9f\xa3\xa2or\xa4`b\xa9\x19\x1a\xaa\x1b\x1d\xaa\xb5\xba\xaa\xb6\xbb\xab\xb2\xb7\xab\xb3\xb8\xab\xb4\xb8\xab\xba\xc0\xb7\x11\x12\xb9\xc4\xc9\xbe\xc0\xc2\xbf\xbb\xbc\xc4\x14\x15\xd0\xde\xe3\xd6\t\t\xd8\n\n\xd8\xe5\xea\xda\n\n\xda\x0b\x0b\xda\xe6\xeb\xdb\xe7\xec\xdc\xe8\xec\xe0\r\r\xe1\r\r\xe2\xec\xef\xe2\xec\xf0\xe4\xe5\xe6\xe7\x10\x10\xe8\xf0\xf3\xec\xea\xeb\xf4\x16\x16\xf5\xf8\xfa\xff\x1a\x1a\xff\xff\xff\xeb\x12-N\x00\x00\x00\x1ctRNS\x00\x01-4\x81\x82\x91\x9d\x9e\x9e\xb0\xb2\xb8\xc1\xd0\xd1\xd8\xd9\xe5\xe9\xf1\xf2\xf2\xfb\xfc\xfd\xfd\xfe(\xffw\x99\x00\x00\x00\xb0IDAT\x18\x19=\xc1\x89\x1a\x81#\x14\x06\xd0\x7f\n\x955Id\xdf\xf7\xc24\xd6\x90\xf5\xfd_\xc9\x1d\xfa:\x07\x92\x92\xc9\x96J\xd9\x8c\x82?\x96\xb6\xde?V\x9a\x81\xb0|\xe3\x19\x85\xfb}\x18=\x1by\x06 \xe5\x9ey\xec\xec\xa6\x00\xa5\x12\xf0DPQ\xa0\xef\xb8\xb4\xd9pi\xa7\xa3\xc8\xa5\xc1l6\xe4R\x11\xd5\x15\x19\xcf\xbb\x9d\xf5hE\xaahzd\xbah\xb7\xfc\x89G\x9a\xb0\x85\xd4\xf7\xfd\x9e\x90l\x14\x8e\x82l\x97\xcb\xad \xc7\x02\xd4\xfaA$\x0eu\x15\xd0n\x17\x11\xbb\xdc4\x00\xac\xfcx\xdd\xaf\xa7\xd3\xf5\xfez\x94\x19\x083j\x9f\x9f\x9a\xc1\xf0\xa7\xe6L\xc71s*\xc8\x17B\xf5#3;\xd8r\xdc\x00\x00\x00\x00IEND\xaeB`\x82'
image_buffer = io.BytesIO(raw_image)
image = pyglet.image.load('temp.png', file=image_buffer)
image_sprite = pyglet.sprite.Sprite(pyglet_image)
If you want to store the pixel data alone, you could extract it like this:
print(image.image_data.get_data('RGBA', 16*4))
Where 'RGBA' is the format you want on the data, and 16*4 is the number of pixels per row times the number of colors per pixel (RBGA is 4).
That will give you the option to do:
raw_data = b'\x00\xae\xff\x00\x00\x00\x00\x00\x00#b\x00\x00q\xa5\x05\x009XI\x00-I\xa8\x00\'A\xe4\x00%?\xfb\x00%?\xfb\x00\'A\xe4\x00-I\xa8\x009XI\x00q\xa5\x05\x00Be\x00\x00\xff\xff\x00\x00\xae\xff\x00\x00\x9e\xe9\x00\x00\r\x1c\x00\x00Hm\x18\x00.I\x92\x00#<\xef\x00"<\xff\x00%B\xff\x00(F\xff\x00(F\xff\x00%B\xff\x00"<\xff\x00#<\xef\x00.I\x92\x00Jo\x18\x00\x00\x00\x00\x00\x9f\xea\x00\x00\xcf\xff\x06\x00a\x93 \x00-I\xb2\x00";\xff\x00)G\xff\x002T\xff\x007[\xff\x00;a\xff\x00;c\xff\x009_\xff\x003V\xff\x00)H\xff\x00"<\xff\x00.L\xb3\x00i\xa0#\x00\xcb\xff\x07\x04\xb7\xff\x1e\x06U\x81\xa0\x00)H\xff\x000U\xff\x00<d\xff\x00Cm\xff\x00Hu\xff\x00O\x82\xff\x06]\x94\xff\x04V\x8b\xff\x00Eq\xff\x00<d\xff\x006_\xff\x013Y\xff\x05V\x86\xa2\x02\xb5\xff!\x02v\xb4f2\x8d\xbf\xf3\x10[\x95\xff\x0b[\x97\xff\x04\\\x9a\xff\x02^\x9e\xff\x0cn\xaf\xff\tu\xc6\xffA\xad\xee\xff5\x9f\xdc\xff\x01Z\x92\xff\x00M\x82\xff!u\xb0\xff?\x9b\xd3\xff(\x88\xbf\xf3\x01u\xb5g\x00#l\xb5+{\xab\xff4\xa0\xea\xff:\xaa\xf6\xff4\xa5\xf0\xff,\xa0\xee\xff;\xb0\xfa\xff4\xaf\xfd\xff8\xb3\xff\xff3\xa9\xf4\xff\x05i\xaf\xff\x00d\xad\xffL\xb0\xec\xff[\xc2\xff\xff$w\xad\xff\x00Am\xb5\x004X\xe7*}\xb1\xffD\xb8\xff\xff\x11\x96\xff\xff:\xb4\xff\xff;\xb7\xff\xff\x0f\x99\xff\xffE\xbf\xff\xff8\xb8\xff\xff1\xac\xf9\xff\x03q\xca\xff\x19\x89\xda\xff9\xb4\xfe\xffE\xbb\xff\xff$y\xb0\xff\x003W\xe7\x001R\xfc+\x80\xb6\xffD\xb9\xff\xff\x10\x97\xff\xff9\xb4\xff\xff;\xb7\xff\xff\x0e\x99\xff\xffE\xbe\xff\xff8\xba\xff\xff1\xaf\xfe\xff\x07\x80\xea\xff1\xa5\xf5\xff\x1d\x9e\xff\xffF\xbb\xff\xff$|\xb3\xff\x001Q\xfc\x001R\xfc+\x80\xb6\xffD\xb8\xff\xff\x10\x93\xff\xff:\xb2\xff\xff;\xb5\xff\xff\x0e\x95\xff\xffE\xbe\xff\xff8\xbc\xff\xff0\xb2\xff\xff\x1f\x9d\xfd\xff&\x9b\xf2\xff\x11\x8b\xf6\xffG\xba\xff\xff${\xb2\xff\x001Q\xfc\x004W\xe7*}\xb2\xffD\xb7\xff\xff\x0f\x88\xf5\xff8\xa8\xf4\xff?\xaf\xf6\xff\x0c\x89\xf7\xffE\xbc\xff\xff8\xbd\xff\xff4\xb9\xff\xff8\xb0\xf9\xff\tx\xcf\xff\x12\x80\xdc\xffG\xb7\xfe\xff$x\xae\xff\x003V\xe7\x00>h\xb3+z\xab\xffE\xb5\xf7\xff\x0fv\xc8\xff\x07g\xaa\xff\tl\xad\xff\nw\xcd\xffG\xbb\xfd\xff7\xb9\xff\xff\\\xc7\xff\xff3\x9b\xdc\xff\x00\\\xa4\xff\x13v\xbd\xffH\xb6\xf6\xff%u\xa6\xff\x00=f\xb2\x00X\x8f^"o\x9c\xf2F\xa5\xd8\xff\tY\x92\xff\x00Iw\xff\x00N|\xff\x04b\x9e\xffB\xab\xe6\xff+\xa0\xee\xff=\xa4\xe6\xff\x0ej\xa6\xff\x00L\x7f\xff\x0b[\x93\xffI\xa7\xd9\xff\x1ek\x97\xf2\x00W\x8c]\x00\xa1\xf0\x17\x02Gq\x9d\x056Y\xff\x002X\xff\x00:_\xff\x00Ah\xff\x00Jw\xff\x04Z\x90\xff\x02Z\x97\xff\x00U\x8e\xff\x00Gt\xff\x00<c\xff\x003Y\xff\x057Z\xff\x02Gp\x9d\x00\xa1\xf0\x16\x00\xfa\xff\x03\x00b\x95\x1f\x00-I\xb3\x00"<\xff\x00)G\xff\x002T\xff\x008]\xff\x00;b\xff\x00<d\xff\x009_\xff\x003V\xff\x00)H\xff\x00"<\xff\x00-I\xb3\x00b\x95\x1f\x00\xff\xff\x03\x00\x8b\xce\x00\x00\x15\'\x00\x00In\x18\x00.I\x92\x00#<\xef\x00"<\xff\x00%B\xff\x00(F\xff\x00(F\xff\x00%B\xff\x00"<\xff\x00#<\xef\x00.I\x92\x00In\x18\x00\x16(\x00\x00\x8a\xcc\x00\x00\xaf\xff\x00\x00\x00\x00\x00\x00Ac\x00\x00q\xa6\x05\x009XI\x00-I\xa8\x00\'A\xe4\x00%?\xfb\x00%?\xfb\x00\'A\xe4\x00-I\xa8\x009XI\x00q\xa6\x05\x00Ad\x00\x00\x00\x00\x00\x00\xaf\xff\x00'
image_sprite = pyglet.sprite.Sprite(pyglet.image.ImageData(16, 16, 'RGBA', raw_data), x=10, y=10)
And in both cases, you'll get a result that looks like this:
According to the docs, you like load an image from a file-like object (like a BytesIO) by specifying the file keyword parameter:
kitten_stream = io.BytesIO(some_bytes)
kitten = pyglet.image.load('kitten.png', file=kitten_stream)
(You may need to rewind the file pointer to the beginning of the file by calling kitten_stream.seek(0) before loading).
Related
Im really struggling with serialized textbuffer data. I just got thru an SQL encoding issue(thanks theGtkNerd for the help.) and now my troubles are back.
Im trying to add search/replace functionality to a textview that is using pixbufs and formated text, since i have images/tags stored in the buffer, i am trying to do the replace on the serialized textview buffer data.
the following code works as long as the replace string is the same size as the searchstr.
def _diagFnRReplaceAll(self,oWidget): #Replace All Function
findbox = self.builder.get_object('FnRFindEntry')
searchstr = findbox.get_text()
buf = self.dataview.get_buffer()
repbox = self.builder.get_object('FnRReplaceEntry')
repstr = repbox.get_text()
format = buf.register_serialize_tagset()
data = buf.serialize(buf, format, buf.get_start_iter(),
buf.get_end_iter())
sys.stdout.buffer.write(data) #< print raw for debugging
newdata = data.replace(bytes(searchstr,'ascii'),bytes(repstr,'ascii'))
print("\n\n\n\n")
sys.stdout.buffer.write(newdata) #< print raw for debugging
buf.set_text('')
format = buf.register_deserialize_tagset()
buf.deserialize(buf, format, buf.get_end_iter(),newdata)
if its smaller or larger i get the following error.
Gtk:ERROR:../../../../gtk/gtktextbufferserialize.c:1588:text_handler: code should not be reached
i tried changing the encoding type, and different ways to encode, but it didnt help. the fact that a same size string works fine makes me think there is a size value for the serialized buffer data or pixbuf data somewhere, but i havnt come up with anything by searching.
i tried to do the replace like you would on a textview without pics, it worked but lost the pic/format data.
Does anyone know why this is happening?
or does anyone know another way i can do a search and replace in a textview widget that has pixbuf data and formatting tags?
well i got it wotking using a little byte patching.I just saw your comment on using marks, i will look into that as i would rather use builtin functionality instead of what im doing. My way is replacing the 4 bytes after the GTKBUFFERCONTENTS-001 with a new 4 byte value for the new size of the buffer.
here is what i have working right now
def _diagFnRReplaceAll(self,oWidget):
findbox = self.builder.get_object('FnRFindEntry')
searchstr = findbox.get_text()
buf = self.dataview.get_buffer()
repbox = self.builder.get_object('FnRReplaceEntry')
repstr = repbox.get_text()
format = buf.register_serialize_tagset()
data = buf.serialize(buf, format, buf.get_start_iter(), buf.get_end_iter())
start_bytes = data[0:26]
size_bytes =data[26:30]
sizeval = int.from_bytes(size_bytes, byteorder='big', signed=False)
end_of_markup = 29 + sizeval +1
the_rest = data[end_of_markup:len(data)]
markup = data[30:end_of_markup]
newmarkup = bytearray(markup.replace(bytes(searchstr,'ascii'),bytes(repstr,'ascii')))
newsize = len(newmarkup).to_bytes(4,'big')
reconstruct =start_bytes + newsize + newmarkup +the_rest
buf.set_text('')
format = buf.register_deserialize_tagset()
buf.deserialize(buf, format, buf.get_end_iter(),reconstruct)
This works without issue so far, i will repost if i get it working with the 'Marks' suggestion. Thanks again theGtknerd.
I have an application that uses bitmaps for image storage. Currently these are stored as uncompressed bitmaps, but since the number of colors is almost always <=16, I should be able to use a compressed bitmap format, which makes the files nearly 6 times smaller. With the help of the Wikipedia entry at https://en.wikipedia.org/wiki/BMP_file_format I tried to implement a compression program in Python - shown below. This successfully reads the input bmp and outputs a smaller bmp, but the resulting bmp is not readable, so I must be doing something wrong. In windows explorer, the properties of the file include "Bit Depth: 32", which is clearly not the intention - but I'm pretty sure I got the header info for bit depth and compression right. It would help if I could find an example of a compressed bitmap for inspection, but haven't been able to track one down. Is this format not generally supported, or am I doing something wrong?
import math
def rgb(r,g,b):
return hex(256*256*256+r*256*256+g*256+b)[3:9]
def read_bmp(path):
bm={}
with open(path,"rb") as f:
byte=f.read(54)
header_size=byte[14]+byte[15]*256
if header_size!=40: return None
bm['w']=w=byte[18]+byte[19]*256
bm['h']=byte[22]+byte[23]*256
bm['color_depth']=byte[28]
bm['compression']=byte[30]
bm['im_size']=byte[34]+byte[35]*256+byte[36]*256*256
if bm['compression']!=0:
ct=f.read(4*bm['color_depth'])
color_table=[]
for i in range(0,bm['color_depth']):
color_table.append((ct[i*4],ct[i*4+1],ct[i*4+2]))
if bm['color_depth']==24:
bmp=f.read(bm['im_size'])
row_size=bm['im_size']//bm['h']
col={}
pixel=[]
for y in range(0,bm['h']):
s=""
row=[]
for x in range(0,w):
row.append((bmp[y*row_size+x*3],bmp[y*row_size+x*3+1],bmp[y*row_size+x*3+2]))
color=rgb(bmp[y*row_size+x*3],bmp[y*row_size+x*3+1],bmp[y*row_size+x*3+2])
if color in col:
col[color]+=1
else:
col[color]=1
pixel.append(row)
bm['pix']=pixel
bm['color_count']=len(col)
return bm
def putint(b,p,i):
b[p]=i & 255
b[p+1]=(i>>8)&255
if i>65535:
b[p+2]=(i>>16)&255
b[p+3]=(i>>24)&255
def write_compressed_bmp(bm,path):
pix=bm['pix']
col=[]
color_index=[]
for row in pix:
rowindex=[]
for color in row:
if not color in col: col.append(color)
rowindex.append(col.index(color))
color_index.append(rowindex)
print(col)
if len(col)>16: return
with open(path,"wb") as f:
row_size=math.ceil(bm['w']/8)*4
image_size=row_size*bm['h']
file_len=54+64+image_size
header=bytearray(54)
header[0]=ord('B')
header[1]=ord('M')
putint(header,2,file_len)
putint(header,10,54+64)
putint(header,14,40)
putint(header,18,bm['w'])
putint(header,22,bm['h'])
putint(header,26,1)
putint(header,28,4)
putint(header,34,image_size)
f.write(header)
color_map=bytearray(64)
for i in range(0,len(col)):
color_map[i*4]=col[i][0]
color_map[i*4+1]=col[i][1]
color_map[i*4+2]=col[i][2]
f.write(color_map)
for row in pix:
row_bytes=bytearray(row_size)
i=0
for color in row:
ci=col.index(color)
if i&1:
row_bytes[i>>1]|=ci
else:
row_bytes[i>>1]|=ci<<4
i+=1
f.write(row_bytes)
bm=read_bmp("bitmap.bmp")
if bm['color_count']<=16:
write_compressed_bmp(bm,"bitmap2.bmp")
I found out what was wrong - I forgot that the range() method in Python takes one larger than the largest desired value as its second parameter, so one too few rows was being written. Fixing that, and leaving the "compression" bit at 0 fixed the problem - I edited the code above accordingly. If it's OK, I'll leave this up here for possible use by others.
I am new to google earth engine and was trying to understand how to use the Google Earth Engine python api. I can create an image collection, but apparently the getdownloadurl() method operates only on individual images. So I am trying to understand how to iterate over and download all of the images in the collection.
Here is my basic code. I broke it out in great detail for some other work I am doing.
import ee
ee.Initialize()
col = ee.ImageCollection('LANDSAT/LC08/C01/T1')
col.filterDate('1/1/2015', '4/30/2015')
pt = ee.Geometry.Point([-2.40986111110000012, 26.76033333330000019])
buff = pt.buffer(300)
region = ee.Feature.bounds(buff)
col.filterBounds(region)
So I pulled the Landsat collection, filtered by date and a buffer geometry. So I should have something like 7-8 images in the collection (with all bands).
However, I could not seem to get iteration to work over the collection.
for example:
for i in col:
print(i)
The error indicates TypeError: 'ImageCollection' object is not iterable
So if the collection is not iterable, how can I access the individual images?
Once I have an image, I should be able to use the usual
path = col[i].getDownloadUrl({
'scale': 30,
'crs': 'EPSG:4326',
'region': region
})
It's a good idea to use ee.batch.Export for this. Also, it's good practice to avoid mixing client and server functions (reference). For that reason, a for-loop can be used, since Export is a client function. Here's a simple example to get you started:
import ee
ee.Initialize()
rectangle = ee.Geometry.Rectangle([-1, -1, 1, 1])
sillyCollection = ee.ImageCollection([ee.Image(1), ee.Image(2), ee.Image(3)])
# This is OK for small collections
collectionList = sillyCollection.toList(sillyCollection.size())
collectionSize = collectionList.size().getInfo()
for i in xrange(collectionSize):
ee.batch.Export.image.toDrive(
image = ee.Image(collectionList.get(i)).clip(rectangle),
fileNamePrefix = 'foo' + str(i + 1),
dimensions = '128x128').start()
Note that converting a collection to a list in this manner is also dangerous for large collections (reference). However, this is probably the most scalable method if you really need to download.
Here is my solution:
import ee
ee.Initialize()
pt = ee.Geometry.Point([-2.40986111110000012, 26.76033333330000019])
region = pt.buffer(10)
col = ee.ImageCollection('LANDSAT/LC08/C01/T1')\
.filterDate('2015-01-01','2015-04-30')\
.filterBounds(region)
bands = ['B4','B5'] #Change it!
def accumulate(image,img):
name_image = image.get('system:index')
image = image.select([0],[name_image])
cumm = ee.Image(img).addBands(image)
return cumm
for band in bands:
col_band = col.map(lambda img: img.select(band)\
.set('system:time_start', img.get('system:time_start'))\
.set('system:index', img.get('system:index')))
# ImageCollection to List
col_list = col_band.toList(col_band.size())
# Define the initial value for iterate.
base = ee.Image(col_list.get(0))
base_name = base.get('system:index')
base = base.select([0], [base_name])
# Eliminate the image 'base'.
new_col = ee.ImageCollection(col_list.splice(0,1))
img_cummulative = ee.Image(new_col.iterate(accumulate,base))
task = ee.batch.Export.image.toDrive(
image = img_cummulative.clip(region),
folder = 'landsat',
fileNamePrefix = band,
scale = 30).start()
print('Export Image '+ band+ ' was submitted, please wait ...')
img_cummulative.bandNames().getInfo()
A reproducible example can you found it here: https://colab.research.google.com/drive/1Nv8-l20l82nIQ946WR1iOkr-4b_QhISu
You could possibly use ee.ImageCollection.iterate() with a function that gets the image and adds it to a list.
import ee
def accumluate_images(image, images):
images.append(image)
return images
for img in col.iterate(accumulate_images, []):
url = img.getDownloadURL(dict(scale=30, crs='EPSG:4326', region=region))
Unfortunately I am not able to test this code as I do not have access to the API, but it might help you arrive at a solution.
I have a similar problem and was not able o solve with presented solutions. Then I have elaborated a sample code for this purpose. It iterates over an image collection in client side, then it is not affected by limitations (server side only) of .map() or .iterate().
It is possible to download the code and see its explanation here
It basically transform the ImageCollection into a list (ic.toList()). Then it performs a standard loop, and for each individual image it is possible to convert it back to ee.Image(list.get(i)), and then process one by one taking all images in the collection.
In your particular case, to download each image, the function to be called within the loop could be: getDOwnloadURL() or getThumbURL():
var url = imgNew.getDownloadURL({
region: geometry,
});
var thumbURL = imgNew.getThumbURL({region: geometry,dimensions: 512, format: 'png'});
I am using a simple code to compare an image to a desktop screenshot through the function getcolors() from PIL. When I open an image, it works:
im = Image.open('sprites\Bowser\BowserOriginal.png')
current_sprite = im.getcolors()
print current_sprite
However, using both pyautogui.screenshot() and ImageGrab.grab() for the screenshot, my code returns none. I have tried using the RGB conversion as shown here: Cannot use im.getcolors.
Additionally, even when I save a screenshot to a .png, it STILL returns none.
i = pyautogui.screenshot('screenshot.png')
f = Image.open('screenshot.png')
im = f.convert('RGB')
search_image = im.getcolors()
print search_image
First time posting, help is much appreciated.
Pretty old question but for those who sees this now:
Image.getcolors() takes as a parameter "maxcolors – Maximum number of colors." (from the docs here).
The maximum number of colors an image can have, equals to the number of pixels it contains.
For example, an image of 50*60px will have maximum 3,000 colors.
To translate it into code, try this:
# Open the image.
img = Image.open("test.jpg")
# Set the maxcolors number to the image's pixels number.
colors = img.getcolors(img.size[0]*img.size[1])
If you'd check the docs, getcolors returns None if the number of colors in the image is greater than the default parameter, which is set to 256.
I have 4 directories with images for an animation. I would like to take the set of images and generate a single image with the 4 images arranged into a 2x2 grid for each frame of the animation.
My code so far is:
import Image
fluid64 = "Fluid64_half_size/00"
fluid128 = "Fluid128_half_size/00"
fluid512 = "Fluid512_half_size/00"
fluid1024 = "Fluid1024_half_size/00"
out_image = "Fluid_all/00"
for pic in range(1, 26):
blank_image = Image.open("blank.jpg")
if pic < 10:
image_num = "0"+str(pic)
else:
image_num = str(pic)
image64 = Image.open(fluid64+image_num+".jpg")
image128 = Image.open(fluid128+image_num+".jpg")
image512 = Image.open(fluid512+image_num+".jpg")
image1024 = Image.open(fluid1024+image_num+".jpg")
out = out_image + image_num + ".jpg"
blank_image.paste(image64, (0,0)).paste(fluid128, (400,0)).paste(fluid512, (0,300)).paste(fluid1024, (400,300)).save(out)
Not sure why it's not working. I'm getting the error:
Traceback (most recent call last):
File "C:\Users\Casey\Desktop\Image_composite.py", line 24, in <module>
blank_image.paste(image64, (0,0)).paste(fluid128, (400,0)).paste(fluid512, (
ste(fluid1024, (400,300)).save(out)
AttributeError: 'NoneType' object has no attribute 'paste'
shell returned 1
Any help would be awesome. Thanks!
The only problem there is that "paste" does not return an image object - it rather modifies the "blank" image inplace.
So, when the second paste is called (the one that uses the fuild128 image), it tries to be applied on "None" - which is the return value of the first image.
If that is the only problem you are having, just make one paste call per line, like this:
blank_image.paste(image64, (0,0))
blank_image.paste(fluid128, (400,0))
blank_image.paste(fluid512, (0,300))
blank_image.paste(fluid1024, (400,300))
blank_image.save(out)
Although it looks likely you'd need to scale each image so that their format match as well.
And your code for the "image_num" variable is unecessary. Python is really good with strings - just do something like this:
image64 = Image.open(fluid64 + "%02d.jpg" % pic)
You may want to be using something along the lines of :
blank_image = Image.new("RGB", (800, 600))
This will create a new area in memory in which you can generate your image. You should then be able to paste you images into that.
Then you'll need to save it out again later on with:
blank_image.save("blank.jpg")
Read the error message:
AttributeError: 'NoneType' object has no attribute 'paste'
This means you tried to call .paste on something that was of type NoneType, i.e. on the None object.
Image.paste returns None. You can't "chain" together calls like that except when the functions are specifically designed to support it, and Image.paste is not. (Support for this sort of thing is accomplished by having the function return self. You get an error that talks about NoneType because the function is written not to return anything, and everything in Python returns None by default if nothing else is returned explicitly.) This is considered Pythonic: methods either return a new value, or modify self and return None. Thus, so-called "fluent interfaces" are not used when the functions have side effects - Pythonistas consider that harmful. Returning None is a warning that the function has side effects. :)
Just do four separate .paste calls.
Tiling figures in a 2-by-2 grid would be easy to achieve with the append_images function defined in this reply
https://stackoverflow.com/a/46623632/8738113
For example:
img1 = append_images([image64, image128], direction='horizontal')
img2 = append_images([image512, image1024], direction='horizontal')
final = append_images([img1, img2], direction='vertical')
final.save("Fluid_all/00.jpg")
Unlike PIL APIs copy, crop, resize or rotate which return an Image object, paste returns None which prevents chained method calls. Not so convenient API design.