boi4/dynwalls

Couldn't Write Image

UnPossible-Me opened this issue · 14 comments

Hello,
This seems like a fantastic project that could allow me to easily use and swap dynamic wallpapers. So Kudos to the devs for than.
Unfortunately I've run into a couple of issues, which I just can not figure out. I'm pretty much a beginner and still learning, apologies for any mistakes.

I've read though the previous issues and #3 was a godsend. I'll list out everything I've encountered and resolved using it.
My system is Zorin OS 15
gnome-panel 3.26.0

Right off the bat, same thing happened to me with heif convert, I'd installed libheif-dev.
libheif-examples fixed that problem.
Along those lines, the package for exiftool was libimage-exiftool-perl.

dynwalls setcmd 'feh --bg-fill --no-fehbg {}' didn't work for me either, but the other command, gsettings set org.gnome.desktop.background picture-uri 'file:///home/rinzler/.local/share/dynwalls/images/wallpaper-1.jpg' did work without a hitch.
The output of cat ~/.local/share/dynwalls/config.json should be needed is:

{"wp_cmd": "gsettings set org.gnome.desktop.background picture-uri \"file://{}\"", "dyn_config": {"ti": [{"t": 0.0, "i": 0}, {"t": 0.125, "i": 1}, {"t": 0.25, "i": 2}, {"t": 0.375, "i": 3}, {"t": 0.5, "i": 4}, {"t": 0.625, "i": 5}, {"t": 0.75, "i": 6}, {"t": 0.875, "i": 7}], "ap": {"d": 7, "l": 0}}}

After that, python3 dynwalls setcmd "gsettings set org.gnome.desktop.background picture-uri file://{}" resulted in Successfully updated wallpaper command.

Great? Now I should be able to use the "dynwalls use command" right?
Executing python3 dynwalls use ./Wallpapers/Big-macOS-Sur.heic (Wallpapers is a directory I created) returns:

Could not read HEIF file: Invalid input: No 'meta' box
Usage:
  gsettings [--schemadir SCHEMADIR] get SCHEMA[:PATH] KEY

Get the value of KEY

Arguments:
  SCHEMADIR A directory to search for additional schemas
  SCHEMA    The name of the schema
  PATH      The path, for relocatable schemas
  KEY       The key within the schema

Well... perhaps a bad file, I tried again with python3 dynwalls use ./Wallpapers/Dome.heic, this returns:

File contains 2 images
Can't open /home/rinzler/-1.local/share/dynwalls/images/wallpaper.jpg: No such file or directory
could not write image
Can't open /home/rinzler/-2.local/share/dynwalls/images/wallpaper.jpg: No such file or directory
could not write image
Usage:
  gsettings [--schemadir SCHEMADIR] get SCHEMA[:PATH] KEY

Get the value of KEY

Arguments:
  SCHEMADIR A directory to search for additional schemas
  SCHEMA    The name of the schema
  PATH      The path, for relocatable schemas
  KEY       The key within the schema

This message:
Oh you should probably use set and not get, sorry :D
Originally posted by @boi4 in #3 (comment)

Helps solve something, now the outputs are:
For python3 dynwalls use ./Wallpapers/Big-macOS-Sur.heic:

Could not read HEIF file: Invalid input: No 'meta' box

And python3 dynwalls use ./Wallpapers/Dome.heic:

File contains 2 images
Can't open /home/rinzler/-1.local/share/dynwalls/images/wallpaper.jpg: No such file or directory
could not write image
Can't open /home/rinzler/-2.local/share/dynwalls/images/wallpaper.jpg: No such file or directory
could not write image

At this point while @ng2303's wallpaper at least applied, I couldn't, but I haven't yet run dynwalls enable if that matters.
My ~/.local/share/dynwalls/images directory is very much empty at this point.

Now, while python3 dynwalls setcmd "gsettings set org.gnome.desktop.background picture-uri file://{}" still returned Successfully updated wallpaper command., it didn't solve the above problem of using the wallpaper.

Yes it should have been setcmd. Okay run this:

systemctl --user disable dynwalls.timer
rm ~/.local/share/systemd/user/dynwalls.timer
rm ~/.local/share/systemd/user/dynwalls.service
rm -r ~/.local/share/dynwalls
systemctl --user daemon-reload

# in the dynwalls directory
git checkout master
python3 dynwalls setcmd "gsettings set org.gnome.desktop.background picture-uri file://{}"
python3 dynwalls use PATH_TO_HEIC
python3 dynwalls enable

Try to understand what these commands do before you use them.

Sorry for all the hassle, I think I will maybe run popos on a vm for testing and check whether this works.

Originally posted by @boi4 in #3 (comment)

I do understand what these do, and ran successfully, but trying to use my wallpaper, it's still:

File contains 2 images
Can't open /home/rinzler/-1.local/share/dynwalls/images/wallpaper.jpg: No such file or directory
could not write image
Can't open /home/rinzler/-2.local/share/dynwalls/images/wallpaper.jpg: No such file or directory
could not write image

I ran the command by @flohw python3 dynwalls setcmd 'gsettings set org.gnome.desktop.background picture-uri "file://{}" , but that doesn't fix the problem.

That was a terribly long winded explanation, but I wanted there to be as little confusion as possible, I can see that dynwalls is trying to use /home/rinzler/**-1.**local and /home/rinzler/**-2**.local instead of /home/rinzler/.local, but there's nothing on the internet, so I'm lost.

And as for journalctl --user -u dynwalls, well, there are no logs.

All my wallpaper are from Dynamic Wallpaper Club so they should work perfectly?

boi4 commented

Hi @UnPossible-Me ,
I am happy that you like the idea of the project :)

You are right, it seems that the use command seems to use the wrong path.
I quickly glanced over some parts of the code, but couldn't find the problem.

I think it could actually be a problem of heif-convert.

Can you try running

mkdir -p /home/rinzler/.local/share/dynwalls/images/
heif-convert -q 100 ./Wallpapers/Dome.heic /home/rinzler/.local/share/dynwalls/images/wallpaper.jpg

manually and tell me the output?

If you have time, please add the following line to https://github.com/boi4/dynwalls/blob/master/dynwalls/heic.py#L30 (right under the TODO comment):

print(f"{fname=}, {outputdir=}, {filename_prefix=}, {extension=}")

Then run the use command again and tell me the output.
Hopefully, it becomes clear then what the problem is.

boi4 commented

I just changed the first command, if you ran it already before my edit, please run:

rmdir  /home/rinzler/.local/share/dynwalls/images/wallpaper.jpg
boi4 commented

Here is the source code of heif-convert:
https://github.com/strukturag/libheif/blob/c1674b500c62f59f10af10c29eccfb79fd3b1faf/examples/heif_convert.cc#L115

They use rfind to find the last dot character in the output filename and then put these -1, -2, ... things in front of it.

It's really strange that in your case the program finds the dot character in front of the local/share/dynwalls/... and adds these numbers at the wrong place.

Then run the use command again and tell me the output.
Hopefully, it becomes clear then what the problem is.

Thanks for the prompt replay, can't say the same for myself, got swamped yesterday.
Anyhow,
I've run all three commands you've sent, and there's still no change, They're still using the incorrect path.

Now, modifying the heic.py file does change things a bit.

  1. No change when running the heif-convert command you've sent.
  2. Running python3 dynwalls use ./Wallpapers/Dome.heic results in:
Traceback (most recent call last):
  File "/usr/lib/python3.6/runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "/usr/lib/python3.6/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "dynwalls/__main__.py", line 11, in <module>
    import heic
  File "<fstring>", line 1
    (fname=)
          ^

Note: I've indented the command with the rest of the block, without it I get a unexpected indent error.

Alright, got an update:

I go the wallpaper to set.
Instead of using heif-convert -q 100 ./Wallpapers/Dome.heic /home/rinzler/.local/share/dynwalls/images/wallpaper.jpg,
I cd'd into the dynwalls/images directory and ran heif-convert -q 100 /home/rinzler/Projects/dynwalls/Wallpapers/Dome.heic wallpaper.jpg.
This gave me:

File contains 2 images
Written to wallpaper-1.jpg
Written to wallpaper-2.jpg

And the Dark Theme Wallpaper was successfully applied.
Now, how do I test if it's changing?
I used the commands you gave here:

a) wait (it's 6 hours each picture in your case) or
b) use the gsettings get org.gnome.desktop.background picture-uri 'file://' with some random picture (this will overwrite the current background) and then run systemctl --user start dynwalls which will simulate the triggering of a new wallpaper by time. If the wallpaper changes after that command everything should work fine.

Originally posted by @boi4 in #3 (comment)

Waiting is for the wise, so b) it is,
I ran gsettings set org.gnome.desktop.background picture-uri 'file:///home/rinzler/Pictures/screenshot.png' which applied the photo successfully.
Now running systemctl --user start dynwalls it still shows the dark theme wallpaper (which it should as it's past 12PM for me), but it isn't changing as you mentioned. Since @ng2303 also encoutered the same, but changed accordingly with the time, perhaps there's an error with the command?
Time will tell.

Oh and I also removed the change you gave me for heic.py since that seemed to do more harm than good as the dynwalls command won't work with it present.

boi4 commented

Hey, nice that it works somewhat now. However, I would like to know whether it's a bug in heif-convert.

So please send the output (stdout) of the first command:

mkdir -p /home/rinzler/.local/share/dynwalls/images/
heif-convert -q 100 ./Wallpapers/Dome.heic /home/rinzler/.local/share/dynwalls/images/wallpaper.jpg

The question is whether it will uses the ~/-1.local/... path or not.

I think once we have figured this out, everything should work correctly.

Because of the python format string error: Maybe try:

print("fname=", fname,"  outputdir=", outputdir, "  filename_prefix=", filename_prefix, "  extension=", extension)

(indented once)
instead of the line I sent you before and send me the output (stdout) of dynwalls use ...

boi4 commented

By the way: Cd'ing into the directory is a good idea, maybe I could rewrite the python source code so it will execute the heif-convert command in the directory :)

boi4 commented

I just pushed a new commit that does exactly that. Can you pull the latest version and try to setup your wallpaper using the steps from the readme?

mkdir -p /home/rinzler/.local/share/dynwalls/images/
heif-convert -q 100 ./Wallpapers/Dome.heic /home/rinzler/.local/share/dynwalls/images/wallpaper.jpg

Ahh I meant the answer to that was the same output as before in my reply.
The first command runs successfully, it creates the directory.
The heif-convert command returns:

File contains 2 images
Can't open /home/rinzler/-1.local/share/dynwalls/images/wallpaper.jpg: No such file or directory
could not write image
Can't open /home/rinzler/-2.local/share/dynwalls/images/wallpaper.jpg: No such file or directory
could not write image

This time, the python command does run, when I use python3 dynwalls use ./Wallpapers//Dome.heic, I now get:

fname= ./Wallpapers//Dome.heic   outputdir= /home/rinzler/.local/share/dynwalls/images   filename_prefix= wallpaper   extension= jpg
File contains 2 images
Can't open /home/rinzler/-1.local/share/dynwalls/images/wallpaper.jpg: No such file or directory
could not write image
Can't open /home/rinzler/-2.local/share/dynwalls/images/wallpaper.jpg: No such file or directory
could not write image

I pulled the latest commit, and... dynwalls commands started working!
python3 dynwalls use ./Wallpapers/Dome.heic gives:

File contains 2 images
Written to wallpaper-1.jpg
Written to wallpaper-2.jpg

But the heif-convert -q 100 ./Wallpapers/Dome.heic /home/rinzler/.local/share/dynwalls/images/wallpaper.jpg still gives:

File contains 2 images
Can't open /home/rinzler/-1.local/share/dynwalls/images/wallpaper.jpg: No such file or directory
could not write image
Can't open /home/rinzler/-2.local/share/dynwalls/images/wallpaper.jpg: No such file or directory
could not write image

The systemctl --user cat dynwalls.timer timing system also seems to have magically fixed itself apparently.
When switching between wallpapers, the auto timing sequence would not change for the original, but works just fine now.

boi4 commented

Awesome, I will close this issue for now. If you get any new problems regarding the heif-convert command, I can reopen it :)

Nope. no new problems, I was going to close it myself, just a couple of questions if you could:

  1. Day/Night wallpapers aren't supported that's mentioned, but some wallpapers, importantly all MacOS originals encounter an error while applying:
Could not read HEIF file: Invalid input: No 'meta' box
An error occured when extracting the file.

This probably doesn't have anything to do with dynwalls, but what could be the problem/and solution possible?

And finally, a massive thank you!
I wasn't expecting everything to be fixed going into it, but you did, and that's fantastic. :)

@boi4 Apologies for the ping, but have you seen this? I can't tell.

The wallpaper(I've renamed it to .txt so I can attach here):
Big-Sur-Beach 2.heic.txt

boi4 commented

Hi @UnPossible-Me ,
I have read your comment but didn't have time to respond yet.
Where do you have the original Mac OS wallpapers from? Can you send me one of the files via E-Mail?

Maybe I can tell you a little bit about the internals of these dynamic wallpapers:

  • A dynamic wallpaper is stored in a HEIF (or HEIC) file
  • A HEIF file is a container format that can contain mutliple Pictures and metadata
  • The HEIF-metadata of a dynamic wallpaper should either contain a H24 or a Solar key.
  • The H24 key will store information about when each of the images should be displayed in a time-based manner
  • The Solar key will store some information about when each of the images should be displayed in a sun angle manner (this isn't supported by dynwalls, but dynwalls should tell you that)
  • You can view HEIF-metadata using exiftool wallpaper.heif, the keys are encoded in base64, which then in turn is in Apple's plist format

So I think that the error could have to do something with the exiftool command that is run internally by dynwalls.
Maybe your HEIF file does not contain metadata? But still that would be really strange, because then it wouldn't be suitable as a dynamic wallpaper? I am not sure honestly. If you want to you can try to run exiftool yourself.