Skip to content

Add editing media features into the app gallery#37

Open
Joas329 wants to merge 62 commits intoforkyfrom
feature/forky/edit-media
Open

Add editing media features into the app gallery#37
Joas329 wants to merge 62 commits intoforkyfrom
feature/forky/edit-media

Conversation

@Joas329
Copy link
Collaborator

@Joas329 Joas329 commented Jan 30, 2026

This PR adds the following features into the gallery:
--> File name editing within mediaView and editView Navigation pages.
--> Ability to crop an image
--> Ability to add predetermined filters into pictures only

Tho it is imperative to say that this is only for pictures, no video editing has been applied at all.

This PR also fixes the following issues:
#29
#36

* Edit view is created as a navigation page and opened from the setttings of the mediaView page.

* Add initial layout for the editing bar at the bottom.

Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
… database and refresh media_view and grid_view.

Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
…self already.

Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
…the widget.

Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
…for the user.

Its very bare bones right now, it resets everytime you click outside of the image, but, a win is a win.

* The actual saving to storage and cropping is yet to be added, this ony GTK4 so far.

Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
* Use high-quality (95%) JPEG encoding since JPEG is lossy and byte-for-byte preservation is not possible.

Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
…or overwritting the current image.

* Use the cropping function from media tools.
* TODO: Refresh edit view, media view, grid view (probably usng a signal when changed in database will help me avoid the other multiple signal path."

Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
…k.Stroke.

Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
…ar that has stroke color and size options.

Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
…e coordinates. Therefore, implement a simple coordinate frame change helper.

Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
…tures.

Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
…and encode with GdkPixbuf for non-PNG formats.

For some reason, cairo can only saved directly to PNG, so to maintain image, we convert to pixbuff and save it from there.

Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
…mponent reutilizable.

Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
…s a css class to the image. TODO: Save the transformed image.

I also noticed that we can create the bar in the class and just return it to the parent context.

Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
…e not linear, so we cant just linearly increase each channel, so for now, lets use a naive solution.

Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
…nformations in 8-bit channels.

Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
…the actual images.

Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
… the directories ~/Pictures and ~/Videos.

* This one also checks albums within root ones recursively.

* I still need to use events to update the UI components, but for now it detects new files created, copied and edited from edit_view.

Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
…aling of new files created.

Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
* Solves issue: #36.

Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
…pport for videos yet.

Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
… file is added.

Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
… handled as well.

Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
…bject.

Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
… title and give a default case.

Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
…nstead of a new instance.

Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
…els take up to 30s to complete and it can trigger a Wayland compositor disconnect.

TODO: Find a way to use GPU acceleration or a quicker way to perform the blur.
Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
@FakeShell
Copy link
Contributor

whats the status of this

…om NavigationView.

Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
…his one does not update on delete, since its an attribute of the flowbox child set by us.

Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
@Joas329
Copy link
Collaborator Author

Joas329 commented Feb 24, 2026

So far:
--> Cropping works
--> Filters work
--> Drawing work
--> Fixed indexing issues when adding media (photo taken, saved into directory) and when deleting media as well.

Problem:
--> The some of the image operators, hog a lot of memory and it can trigger the wayland compositor to crash...

I tried using the TFT but its c++ based, So im stuck into seeing how to make the algorithms faster or how to off load the operators to a c++ object and call it when needed.

Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>
Signed-off-by: Joaquin Philco <joaquinphilco@hotmail.com>

return np.stack([R, G, B], axis=-1)

class FuriOSMediaTools:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

everything in this class is a staticmethod with no class variables. maybe split this file to color_space_standards that house the aforementioned class, and rename this file to media_tools then move everything outside FuriOSMediaTools. open to ideas.

you also throw lots of ValueError, FileNotFoundError and TypeError here. are they ever caught?

)

self.on_drawing_cancel_clicked(btn)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

trailing newline

return self.bar

def build_crop_bar(self):
if getattr(self, "crop_bar", None):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where is self.crop_bar defined/used? if defined at all, why not initialize it to a default value in __init__ and check for if self.crop_bar?

self,
picture_widget: Gtk.Widget,
texture: Gdk.Texture,
*,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you don't really need this, we own the internal API, no need to enforce positional arguments

self.edit_bar = bar

def set_edit_bar_visible(self, visible: bool):
if getattr(self, "edit_bar", None):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

initialize self.edit_bar to None in __init__ and use if self.edit_bar instead of getattr

Comment on lines +65 to +71
def on_cancel_clicked(self, btn=None):
if callable(getattr(self, "on_cancel", None)):
self.on_cancel()

def on_apply_clicked(self, btn=None):
if callable(getattr(self, "on_apply", None)):
self.on_apply(getattr(self, "selected_filter", "filter-original"))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

initialize on_cancel and on_apply and set to None in init and use if self.on_cancel and if self.on_apply

self.zoomable_image.set_zoom_enabled(False)
self.set_edit_bar_visible(False)

if getattr(self, "draw_overlay", None):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

initialize self.draw_overlay set to None in init and use if self.draw_overlay

self.draw_overlay.queue_draw()

def on_drawing_cancel_clicked(self, _btn=None):
draw = getattr(self, "draw_overlay", None)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same comment as above

Comment on lines +125 to +131
def on_cancel_clicked(self, _btn):
if callable(getattr(self, "on_cancel", None)):
self.on_cancel()

def on_apply_clicked(self, _btn):
if callable(getattr(self, "on_apply", None)):
self.on_apply(getattr(self, "selected_filter", "filter-original"))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

initialize on_cancel and on_apply and set to None in init and use if self.on_cancel and if self.on_apply


def set_zoom_enabled(self, enabled: bool):
self.zoom_enabled = enabled
if not enabled and getattr(self, "zoom_gesture", None):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

initialize self.zoom_gesture to None in __init__ and check if self.zoom_gesture

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants