Hello!
I observed what appears to be SFML sf::Texture sometimes succeeding, sometimes failing to load
the same image, completely unchanged.
I basically have two programs, one SFML C++ program which reads an image into a texture and displays it at regular intervals, and a non-SFML Python program which creates the images and signals it to the SFML one.
Program 2 sends a unix signal (SIGUSR1) to Program 1, which handles it by loading the image into a texture. Program 2 creates and signals at intervals of 1 second.
Output (Program 1):
SIGUSR1 from 10491
updating...
Failed to load image "/tmp/windowsystem/10491/content.png". Reason: Image not of any known type, or corrupt
SIGUSR1 from 10491
updating...
Failed to load image "/tmp/windowsystem/10491/content.png". Reason: Image not of any known type, or corrupt
SIGUSR1 from 10491
updating...
SIGUSR1 from 10491
updating...
Failed to load image "/tmp/windowsystem/10491/content.png". Reason: Image not of any known type, or corrupt
SIGUSR1 from 10491
updating...
Failed to load image "/tmp/windowsystem/10491/content.png". Reason: Image not of any known type, or corrupt
I opened the files in an image viewer, and they're perfectly fine.
I thought Program 2 must be messing up the images once in a while, so I modified it to calculate the md5sum of the files each time it writes them.
Output (Program 2):
3cc40514ca5de45c6a3eecb0eb0490ff /tmp/windowsystem/10491/content.png
3cc40514ca5de45c6a3eecb0eb0490ff /tmp/windowsystem/10491/content.png
3cc40514ca5de45c6a3eecb0eb0490ff /tmp/windowsystem/10491/content.png
3cc40514ca5de45c6a3eecb0eb0490ff /tmp/windowsystem/10491/content.png
3cc40514ca5de45c6a3eecb0eb0490ff /tmp/windowsystem/10491/content.png
3cc40514ca5de45c6a3eecb0eb0490ff /tmp/windowsystem/10491/content.png
3cc40514ca5de45c6a3eecb0eb0490ff /tmp/windowsystem/10491/content.png
3cc40514ca5de45c6a3eecb0eb0490ff /tmp/windowsystem/10491/content.png
Clearly, the image is unchanged.
I'll post relevant snippets of code here:
Program 1:
// executed whenever it receives SIGUSR1
std::cout << "updating..." << std::endl;
std::string imagefname = path_join({COMMS_DIR, std::to_string(win.pid), "content.png"});
win.content_texture.loadFromFile(imagefname, sf::IntRect());
// changing empty sf::IntRect to one with the known size of the image does not help either...
Program 2:
img = Image.new("RGB", (300, 300), (255, 255, 255))
img.save(os.path.join(comms_app_dir, "content.png"))
os.system("md5sum " + os.path.join(comms_app_dir, "content.png"))
while True:
img.save(os.path.join(comms_app_dir, "content.png"))
os.system("md5sum " + os.path.join(comms_app_dir, "content.png"))
time.sleep(1)
# [... snip ...]
os.kill(wm_pid, signal.SIGUSR1)
# changing up the order of time.sleep() and os.kill() doesn't help...
Note that a different approach in Program 2, on the other hand, works:
while True:
img=Image.new("RGBA", (300, 200), (255, 255, 255))
draw = ImageDraw.Draw(img)
draw.text((0, 0), sp.check_output(["date", "+%F %H:%M %Z"]).decode("utf-8"), (0,0,0), font=font)
draw = ImageDraw.Draw(img)
img.save(os.path.join(comms_app_dir, "content.png"))
os.kill(wm_pid, signal.SIGUSR1)
time.sleep(1)
In this second approach, a new Python image object is created each loop, but this seems to work error-free so far, despite actually modifying the image!
Output (Program 1):
SIGUSR1 from 12014
updating...
SIGUSR1 from 12014
updating...
SIGUSR1 from 12014
updating...
SIGUSR1 from 12014
updating...
SIGUSR1 from 12014
updating...
SIGUSR1 from 12014
updating...
SIGUSR1 from 12014
updating...
SIGUSR1 from 12014
updating...
(and so on for a hundred lines without errors, again at 1 second intervals)
somehow this works!
But my question is that clearly the other approach doesn't even change the file, yet why does SFML have trouble reading it?
Thanks in advance!