Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update images on modifications #137

Merged
merged 1 commit into from
Mar 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions lua/image/image.lua
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ function Image:brightness(brightness)

self.path = altered_path
self.cropped_path = altered_path
self.resize_hash = nil
self.date_hash = nil
self.cropped_hash = nil
self.resize_hash = nil
if self.is_rendered then
Expand All @@ -186,7 +186,7 @@ function Image:saturation(saturation)

self.path = altered_path
self.cropped_path = altered_path
self.resize_hash = nil
self.date_hash = nil
self.cropped_hash = nil
self.resize_hash = nil
if self.is_rendered then
Expand All @@ -206,7 +206,7 @@ function Image:hue(hue)

self.path = altered_path
self.cropped_path = altered_path
self.resize_hash = nil
self.date_hash = nil
self.cropped_hash = nil
self.resize_hash = nil
if self.is_rendered then
Expand Down Expand Up @@ -263,6 +263,7 @@ local from_file = function(path, options, state)
},
with_virtual_padding = opts.with_virtual_padding or false,
is_rendered = false,
date_hash = nil,
crop_hash = nil,
resize_hash = nil,
namespace = opts.namespace or nil,
Expand Down
50 changes: 40 additions & 10 deletions lua/image/renderer.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ local utils = require("image/utils")
-- This is where we keep track of the hashes of the resized and cropped versions of the images so we
-- can avoid processing and writing the same cropped/resized image variant multiple times.
local cache = {
resized = {}, -- { [`${original_path}:${resize_hash}`]: string }
cropped = {}, -- { [`${original_path}:${crop_hash}`]: string }
resized = {}, -- { [`${original_path}:${modification_date}:${resize_hash}`]: string }
cropped = {}, -- { [`${original_path}:${modification_date}:${crop_hash}`]: string }
}

---@param image Image
Expand Down Expand Up @@ -285,6 +285,7 @@ local render = function(image)
local cropped_pixel_height = height * term_size.cell_height
local needs_crop = false
local needs_resize = false
local initial_date_hash = image.date_hash
local initial_crop_hash = image.crop_hash
local initial_resize_hash = image.resize_hash

Expand All @@ -310,10 +311,20 @@ local render = function(image)

-- TODO make this non-blocking

-- modification_date
local magick_image = magick.load_image(image.path)
image.date_hash = magick_image:get_property("date:modify"):gsub("[-:+]", "")
if image.date_hash ~= initial_date_hash then
image:clear()
needs_resize = true
needs_crop = true
end
magick_image:destroy()

-- resize
if needs_resize then
if image.resize_hash ~= resize_hash then
local cached_path = cache.resized[image.path .. ":" .. resize_hash]
if image.resize_hash ~= resize_hash or image.date_hash ~= initial_date_hash then
local cached_path = cache.resized[image.path .. ":" .. image.date_hash .. ":" .. resize_hash]

-- try cache
if cached_path then
Expand All @@ -329,14 +340,21 @@ local render = function(image)
resized_image:set_format("png")
resized_image:scale(pixel_width, pixel_height)

local tmp_path = state.tmp_dir .. "/" .. utils.base64.encode(image.id) .. "-resized-" .. resize_hash .. ".png"
local tmp_path = state.tmp_dir
.. "/"
.. utils.base64.encode(image.id)
.. "-"
.. image.date_hash
.. "-resized-"
.. resize_hash
.. ".png"
resized_image:write(tmp_path)
resized_image:destroy()

image.resized_path = tmp_path
image.resize_hash = resize_hash

cache.resized[image.path .. ":" .. resize_hash] = tmp_path
cache.resized[image.path .. ":" .. image.date_hash .. ":" .. resize_hash] = tmp_path
end
end
end
Expand All @@ -348,8 +366,12 @@ local render = function(image)
-- crop
local crop_hash = ("%d-%d-%d-%d"):format(0, crop_offset_top, pixel_width, cropped_pixel_height)
if needs_crop and not state.backend.features.crop then
if (needs_resize and image.resize_hash ~= resize_hash) or image.crop_hash ~= crop_hash then
local cached_path = cache.cropped[image.path .. ":" .. crop_hash]
if
(needs_resize and image.resize_hash ~= resize_hash)
or image.crop_hash ~= crop_hash
or image.date_hash ~= initial_date_hash
then
local cached_path = cache.cropped[image.path .. ":" .. image.date_hash .. ":" .. crop_hash]

-- try cache;
if cached_path then
Expand All @@ -364,15 +386,22 @@ local render = function(image)
cropped_image:set_format("png")
cropped_image:crop(pixel_width, cropped_pixel_height, 0, crop_offset_top)

local tmp_path = state.tmp_dir .. "/" .. utils.base64.encode(image.id) .. "-cropped-" .. crop_hash .. ".png"
local tmp_path = state.tmp_dir
.. "/"
.. utils.base64.encode(image.id)
.. "-"
.. image.date_hash
.. "-cropped-"
.. crop_hash
.. ".png"
cropped_image:write(tmp_path)
cropped_image:destroy()

image.cropped_path = tmp_path

image.crop_hash = crop_hash

cache.cropped[image.path .. ":" .. crop_hash] = image.cropped_path
cache.cropped[image.path .. ":" .. image.date_hash .. ":" .. crop_hash] = image.cropped_path
end
end
elseif needs_crop then
Expand All @@ -389,6 +418,7 @@ local render = function(image)
and image.rendered_geometry.y == rendered_geometry.y
and image.rendered_geometry.width == rendered_geometry.width
and image.rendered_geometry.height == rendered_geometry.height
and image.date_hash == initial_date_hash
and image.crop_hash == initial_crop_hash
and image.resize_hash == initial_resize_hash
then
Expand Down
1 change: 1 addition & 0 deletions lua/types.lua
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
---@field crop fun(self: MagickImage, width: number, height: number, x?: number, y?: number)
---@field destroy fun(self: MagickImage)
---@field get_format fun(self: MagickImage): string
---@field get_property fun(self: MagickImage, property: string): string
---@field get_height fun(self: MagickImage): number
---@field get_width fun(self: MagickImage): number
---@field modulate fun(self: MagickImage, brightness?: number, saturation?: number, hue?: number)
Expand Down
Loading