以前に画像をbase64に変換し、pickle
で保存した.obj
ファイルがあります。
問題は、.obj
ファイルをpickle
でロードし、コードをbase64からイメージに変換し、pygame
でロードしようとするときです。
画像をロードする関数:
def mainDisplay_load(self):
main_folder = path.dirname(__file__)
img_main_folder = path.join(main_folder, "sd_graphics")
# loadImg
self.mainTerminal = pg.image.load(path.join(img_main_folder, self.main_uncode("tr.obj"))).convert_alpha()
ファイルをデコードする関数:
def main_uncode(self, object):
openFile = open(object, "rb")
str = pickle.load(openFile)
openFile.close()
fileData = base64.b64decode(str)
return fileData
コードを実行するとエラーが発生します:
str = pickle.load(openFile)
EOFError:入力が不足しています
どうすれば修正できますか?
これは、.obj
ファイルの作成に使用したコードです。
import base64, pickle
with open("terminal.png", "rb") as imageFile:
str = base64.b64encode(imageFile.read())
print(str)
file_pi = open("tr.obj","wb")
pickle.dump(str,file_pi)
file_pi.close()
file_pi2 = open("tr.obj","rb")
str2 = pickle.load(file_pi2)
file_pi2.close()
imgdata = base64.b64decode(str2)
filename = 'some_image.jpg' # I assume you have a way of picking unique filenames
with open(filename, 'wb') as f:
f.write(imgdata)
ファイルが作成されると、そのファイルがロードされ、2番目のイメージが作成されます。これは、イメージが同じであるか、変換にエラーがあるかどうかを確認することです。
ご覧のとおり、画像の読み込みにはコードの一部を使用しましたが、保存する代わりにpygame
に読み込まれます。そして、それは間違いが発生する場所です。
やっと解決できました。
メインコードで:
def mainDisplay_load(self):
self.all_graphics = pg.Sprite.Group()
self.graphics_menu = pg.Sprite.Group()
# loadImg
self.img_mainTerminal = mainGraphics(self, 0, 0, "sd_graphics/tr.obj")
グラフィッククラスを含むライブラリ内:
import pygame as pg
import base64 as bs
import pickle as pk
from io import BytesIO as by
from lib.setting import *
class mainGraphics(pg.Sprite.Sprite):
def __init__(self, game, x, y, object):
self.groups = game.all_graphics, game.graphics_menu
pg.Sprite.Sprite.__init__(self, self.groups)
self.game = game
self.object = object
self.outputGraphics = by()
self.x = x
self.y = y
self.eventType()
self.rect = self.image.get_rect()
self.rect.x = self.x * tilesizeDefault
self.rect.y = self.y * tilesizeDefault
def eventType(self):
openFile = open(self.object, "rb")
str = pk.load(openFile)
openFile.close()
self.outputGraphics.write(bs.b64decode(str))
self.outputGraphics.seek(0)
self.image = pg.image.load(self.outputGraphics).convert_alpha()
なぜそんなことをするのかという質問については、簡単です。
十分な動機を持つ攻撃者は、まだ簡単に到達できます
Pythonは無料でオープンです。
一方では、意図的に非表示のデータを変更および回復する人がいます。しかし、もしPythonがより複雑で保護された言語のようにオープン言語であるなら、最もやる気のある人はゲームやプログラムをクラックして同じデータを取得することができます。
一方、基本だけを知っている人もいれば、それさえ知らない人もいます。言語について詳しく知らない、またはファイルをデコードせずにファイルにアクセスできない人。
したがって、私の観点からは、ファイルのデコードはやる気のある人から保護する必要がないことを理解できます。より複雑で保護された言語であっても、そのやる気のある人は自分が望むものを手に入れることができるからです。保護は、言語を知らない人々に対して使用されます。
したがって、エラーが「pickle:run out of input」である場合、上記のコードでディレクトリを台無しにして、obj
と同じ名前の空のファイルを読み取ろうとしている可能性があります。ファイルは。
実際、コードの次の行はそのままです:
self.mainTerminal=pg.image.load(path.join(img_main_folder,self.main_uncode
("tr.obj"))).convert_alpha()
完全に台無しにされています。読むだけで問題を確認できます。ディレクトリ情報なしでファイル名だけをmain_uncode
メソッドに渡します。そして、先ほどコメントで述べたように、たまたまうまくいった場合は、シリアル化されていない画像データを画像の読み取り元のファイル名として使用してみます。 (あなたや他の誰かがおそらくmain_uncode
は一時的な画像ファイルを書き、それに画像データを書き込むべきだと思っていたので、Pygameはそれを読むことができますが、それはそのままで生の画像データを返すだけですストリング)。
したがって、上記の呼び出しを修正して実際のパスをmain_uncode
に渡し、さらに一時データをファイルに書き込んでそのパスを返すようにさらに変更すると、上記のコードのスニペットが修正されます。
2番目の理由は、なぜこの ".obj"ファイルが必要なのかまったくわかりません。バンドルされたファイルが画像を開けないようにするための「隠蔽によるセキュリティ」だけを目的とする場合、これは推奨される方法とはほど遠いものです。 1つだけをまとめると、ファイルの正当な使用を遅らせます(たとえば、あなた自身はそれを使用できないようです)が、十分な動機を持った攻撃者はそれでも簡単にアクセスできます。画像を開いて、base-64エンコードとピクルスを行い、逆のプロセスを実行することで、基本的に何も操作しません。さらに、pickleファイルはシリアル化してディスクコンプレックスに書き込むことができますPythonオブジェクト-ただし、base64による画像のシリアル化は、pickleを必要とせずにファイルに直接書き込むことができます。
3番目:イメージングライブラリで読み込んだファイルだけでなく、with
を使用してすべてのファイルを開くだけです。Pythonについてもう少し学んでください。