0

I am fairly new to Python and am attempting to compile a text (.txt) document that acts as a save file and can be loaded later.

I would like it to be a standalone document that holds all attributes the user is working with (including some images that I would like to be saved in the file as encoded base64 binary strings).

I have written the program and it saves everything to the text file correctly (although I did have to pass the encoded values through a str()) but I am unable to access the images later for decoding. Here is an example of my creation of the text information:

if os.path.isfile("example.png"): #if the user has created this type of image..  
    with open("example.png", "rb") as image_file:
        image_data_base64_encoded_string = base64.b64encode(image_file.read())
        f = open("example_save.txt",'a+')
        f.write("str(image_data_base64_encoded_string)+"\n")
        f.close() #save its information to the text doc

And here is an example of one of my many attempts to re-access this information.

master.filename =  filedialog.askopenfilename(initialdir = "/",title = "Select file",filetypes = ((".txt files","*.txt"),("all files","*.*")))
with open(master.filename) as f:
    image_import = ((f.readlines()[3]))#pulling the specific line the data string is in

image_imported = tk.PhotoImage(data=image_import)

This is only my most recent attempt of many - and still returns an error. I tried decoding the encoded information before passing to the tkinter PhotoImage function but I think that Python may be seeing the encoded information as a string (since I made it one when I saved the information) but I do not know how to change it back without altering the information.

Any help would be appreciated.

Torvoor
  • 57
  • 1
  • 5
  • What is the error you are getting? – Mick_ Apr 02 '18 at 21:51
  • 1
    You have a misplaced double quote in the line that starts with `f.write(`, is that there in the original code sample as well? – wpercy Apr 02 '18 at 21:58
  • 1
    Consider using the `pickle` module for this instead of rolling your own persistence mechanism. – BoarGules Apr 02 '18 at 22:21
  • You have a syntax error that prevents this code from working - there is an unbalanced set of quotes in your first call to `write`. Can you please fix it so that we know exactly what you're doing? – Bryan Oakley Apr 02 '18 at 22:29
  • You are correct, that was a remnant of me removing some unnecessary information. The write portion of the code works in the original formula. – Torvoor Apr 03 '18 at 01:06

2 Answers2

0

When you write out the value as such:

str(image_data_base64_encoded_string)

That's writing it as follows:

b'...blah...'

Look at the file you're writing, you'll find that line is surrounded by b' '.

You want to decode the binary into the appropriate encoding for your file, for example:

f.write(image_data_base64_encoded_string.decode('utf-8') + "\n")
Todd W
  • 398
  • 1
  • 6
  • Would I include this in the original write statement? When I read it back in could I just hand it to PhotoImage in this form? – Torvoor Apr 03 '18 at 01:09
  • I believe so, when you say `str(image_data_base64_encoded_string)` in your existing code it is just showing you a string representation for human readability and the `b'...'`is there to indicate to you the human that it is binary data. When you are writing to a text file, you want to translate the binary to an actual string and the `b'...'` is not intended to be part of the binary translation to the string. – Todd W Apr 03 '18 at 01:51
0

I would recommend using Pillow module for working with images but if you insist on your current way try this code below:

from tkinter import *
import base64
import os

if os.path.isfile("example.png"): #if the user has created this type of image..  
    with open("example.png", "rb") as image_file:
        image_data_base64_encoded_string = base64.b64encode(image_file.read())
        f = open("example_save.txt",'a+')
       f.write(image_data_base64_encoded_string.decode("utf-8")+"\n")
       f.close() 

filename =  filedialog.askopenfilename(initialdir = "/",title = "Select file",filetypes = ((".txt files","*.txt"),("all files","*.*")))
with open(filename) as f:
    image_import = f.readlines()[3].strip()
image_imported = PhotoImage(data=image_import)

You see your string needs to be utf-8 and that trailing newline character is also preventing PhotoImage() from interpreting your image data as image.

Mick_
  • 131
  • 9
  • There's no need to pull in PIL or Pillow. That just brings in extra overhead, and does nothing to solve this problem. – Bryan Oakley Apr 02 '18 at 22:26
  • my bad .. its not needed in this example. – Mick_ Apr 02 '18 at 22:27
  • I do have the PIL module elsewhere in the code and am open to using it here if it would work better! – Torvoor Apr 03 '18 at 01:13
  • I have implemented the above changes and they work beautifully. However, when I attempt to write the imported image to a file (.png) i end up with a scrambled image. I may post a separate question, but any ideas? – Torvoor Apr 03 '18 at 14:20
  • Please use Pillow to write image to the file. You can simply decode the base64 and use BytesIO to pass the data to pillow then save image `frombytes()` – Mick_ Apr 03 '18 at 17:45