views:

66

answers:

3

Ok. Long story short.

My camera has a method which takes a photo and this is what it returns:

[160, 120, 3, 10, 1287848024, 96181, 'super long image string']

I am able to decode the string and save it as image right after I call the method like this:

for i in range(0, 10):
  image = camProxy.getImageRemote(nameId)
  imageWidth = image[0]
  imageHeight = image[1]
  imageByteArray = image[6]
  im = Image.fromstring("YCbCr",(imageWidth,imageHeight),imageByteArray)
  fileName = str(time.time())+".jpg"
  im.save(fileName, "JPEG")

This works nicely and I can open the saved images.

However, if I just save the string into a txt file and later I want to load it and save as image like this:

f = open("rawImage.txt", "r")
data = f.readline()
f.close()

# save as image
im = Image.frombuffer("YCbCr",(160,120),data)
im.save("test.jpg", "JPEG")

What I get is almost completely green image.

Here is an example string which I keep having problems with:

http://richardknop.com/rawImage.txt

Here is a complete output of the getImageRemote() method of the camera for that image:

http://richardknop.com/log.txt

Anybody got ideas what could be wrong? Is this some issue related to encoding? All files are saved as ASCII but I have tried saving them all as UTF-8 as well.

EDIT:

How I have written the image to file? I just redirected the output of the script:

python script.py > output.txt

And in the script I had:

print imageByteArray
+6  A: 

I got it working by changing the file mode from "r" to "rb".

Here's the working code:

import time
import Image
image_data = [160, 120, 3, 10, 1287848024, 96181, 'really long string from http://richardknop.com/log.txt']
imageWidth = image_data[0]
imageHeight = image_data[1]
imageByteArray = image_data[6]
fout = open("image_data.txt", "wb")
fout.write(imageByteArray)
fout.close()
fin = open("image_data.txt", 'rb')
image_string = fin.read()
fin.close()
im = Image.fromstring("YCbCr",(imageWidth,imageHeight),image_string)
fileName = str(time.time())+".jpg"
im.save(fileName, "JPEG")

I verified that you are correct, in that read and readline make no difference here, but I still advise using read, because that says what you mean.

Here's my original answer:

Change data = f.readline() to data = f.read(). read grabs the whole file, readline grabs just one line.

Steven Rumbalski
I think that's not the problem. The text file has just one line. And using read() instead of readline() doesn't help.
Richard Knop
How are you writing the file?
adw
Please give it a try. You have binary data. There is 1 in 256 chance that any single byte will encode to character code 10, a newline. Given that your data is much longer than 256 characters, you are nearly guaranteed that there are newlines there.
Steven Rumbalski
@Richard Knop please check my edited answer.
Steven Rumbalski
@Steven Rumbalski I changed "r" to "rb" and readline to read and I still get the green image. It is supposed to be an image of a room. Did you get the correct image saved on the disk?
Richard Knop
yes, it's very blurry. looks like a large desk in the middle with some items stacked on it. Perhaps you can paste the code where you write the image to file.
Steven Rumbalski
I have added how I saved the image string to file. I have several images saved in txt files like this. Could you also post the code you got working? Because my code generates just a totally green picture (there is no desk, nothing, just green image).
Richard Knop
@Richard Knop My answer now includes the working code.
Steven Rumbalski
Thanks very much.
Richard Knop
The photo is blurry because I used YUV color space to save as much data as possible. I want to create a live video stream from images from the camera installed on a robot and it has to be fast. The resolution will be greater though. I use tiny images like this just for debugging.
Richard Knop
+3  A: 

Maybe you should read and write into your file using binary mode like this :

open('file_name', 'wb')
open('file_name', 'rb')
singularity
+1  A: 

Read in the data:

import Image
import ast

with open('rawImage.txt','r') as f:
   raw_data=f.read()
with open('log.txt','r') as f:
   log_data=f.read()   
log_data=ast.literal_eval(log_data)
imageWidth=log_data[0]
imageHeight=log_data[1]
log_data=log_data[6]        

Let's try to see if raw_data (from rawImage.txt) is the same string as log_data (from log.txt). Oops: they're not the same length:

print(len(raw_data))
# 146843
print(len(log_data))
# 57600

Take a peek at the beginning of both strings. It appears raw_data has written 4 characters for '\x81' when a single character \x81 was intended.

print(list(raw_data[:10]))
# ['6', '}', '\\', 'x', '8', '1', '8', '}', '\\', 'x']
print(list(log_data[:10]))
# ['6', '}', '\x81', '8', '}', '\x81', '7', '\x90', '\x8a', '4']

This might have happened because rawImage.txt was opened in writing mode 'w' instead of 'wb'. The best solution is to write rawImage.txt using the right writing mode, as Steven Rumbalski does here.

But given this predicament, here is a way you can fix it:

raw_data_fixed=raw_data.decode('string_escape') 

Now this works:

im = Image.fromstring("YCbCr",(imageWidth,imageHeight),raw_data_fixed)
im.show()
unutbu