woelper / oculante

A fast and simple image viewer / editor for many operating systems

Home Page:https://github.com/woelper/oculante

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Allowing images bigger than texture size limit without downscale

B-LechCode opened this issue · comments

I have to deal with huge images recently (approx. 4096x128000) as png.
After changing the size limits of the png decoder the image gets resized to 16k on the larger side. 16k is the texture size limit of my GPU/driver combo.

The downside of that solution is the impossibility to zoom in for details in these images.

My idea is to cut the huge image in several textures and display them side by side.
Is there a simpler/better solution?

Yes - it would be awesome if that would be supported. 128000 is a pretty huge! Even if we divide the image into tiles of maximum supported images, that would still be around 2 GB of video memory required, plus 2 GB RAM for the image data, plus 2 GB RAM for the edit buffer plus data in the image cache, so around 4-5 GB RAM + 2 GB VRAM.

I went for simplicity with resizing larger images, but I agree on the use case. In the end, Oculante should support extreme / power user scenarios. I think one solution would be to always treat the texture as an array of tiles which is created once an image comes in. That array would be divided in either one, four, eight etc. tiles which depend on the limits of your graphics hardware.

Thanks for your fast answer :)

Do you have an idea how I could implement it? I don't know notan yet - maybe there is functionality for this.
Otherwise I would think of building a list of structs with texture and it's normalized coordinates for later rendering.

To my knowledge, there is nothing notan-specific. Let me think a bit - but there is something like state.current_image which holds the image data and could remain as is, and state.current_texture, which would probably need to be an array of textures instead of a single one. Next, we could implement slicing up the image and displaying multiple textures (or a grid, with textures mapped).

Ok, should I try to implement or would you like to do it on your own?

Please have a go if you like - I can help if you want!

I think we could start at changing Option<Texture> of current_texture in appstate to something else, like Vec or a struct that has info on how big the texture grid is. There is also an ImageExt trait in utils.rs which turns an image into a texture. That would have to be rewritten to support making more textures out of an Image. The good part is that this happens almost centrally. There are a couple of other cases though, for example when editing an image, the Texture is only updated instead of recreated if the image geometry does not change.

Thank you, I'll give it a try.
When changing "current_texture" there are many sections of code which have to be changed. Will cost me some time to change them all.
There is image editing and the zoom view in the left menu bar which may be some pain to adapt.

Hi @woelper ,
I started to work on this feature.
You can check it out at: https://github.com/B-LechCode/oculante/tree/big_images

I tried to display a 8192x32678 sized png - which worked. It's still early WIP, but maybe interesting for you - any comments are appreciated.
Screenshot_20240421_210409

Nice! Thanks for letting me know! I will take a look soon!

Nice! Thanks for letting me know! I will take a look soon!

Just to post an update: Drawing tiles works, Drawing one image with the tiling option is not yet supported.
The Preview has some small bugs left to fix. Could you please throw an eye on the Code?
If you're fine with it, I would start to refactor and (trying) to fix the bugs.
Do you have an idea for drawing in the old tiled mode?

What I want to refactor:

  • Comments
  • Rename "TexWrap"
  • Put "TexWrap" in a dedicated file (or in utils.rs?)
  • Vectorize the calculations where possible

What do you think? :)

Thank you so much. I would really like to see it in action - would it be ok for you if I made you a contributor and you could transform this into a branch in this repo? I personally have a bit of a hard time either reviewing this in a codespace or checking out other repos.

@woelper for future information you can do this by simply pulling it yourself if you use git cli or the github client, you can also do it with vscode somehow but I dont use it too often so I don't know.

git remote add b-lech https://github.com/B-LechCode/oculante.git
git fetch b-lech big_images:big_images

the syntax of fetch works like
git fetch <remote> <remote-head>:<local-branch>

then you can push the branch to github

as an appendage this works with PRs too
git detch origin pull/<pull req number>/head:local-branch

Thank you so much. I would really like to see it in action - would it be ok for you if I made you a contributor and you could transform this into a branch in this repo? I personally have a bit of a hard time either reviewing this in a codespace or checking out other repos.

Thank you for trusting me! I created a branch "big_images" and created a PR from my fork.
So you can check that branch out after you closed the PR. The size of the texture tiles is reduced to 128 pixels - so it's easier to see the effects of the tiling.

@woelper for future information you can do this by simply pulling it yourself if you use git cli or the github client

Thanks, that is great to know! I am sure I need that in the future!