From 88566b588af071262e73d2af95ff2f5d260066aa Mon Sep 17 00:00:00 2001 From: jonboh Date: Fri, 29 Mar 2024 23:40:18 +0100 Subject: [PATCH] update images on modifications --- lua/image/image.lua | 7 +++--- lua/image/renderer.lua | 50 +++++++++++++++++++++++++++++++++--------- lua/types.lua | 1 + 3 files changed, 45 insertions(+), 13 deletions(-) diff --git a/lua/image/image.lua b/lua/image/image.lua index b4de0a0..cf6eb00 100644 --- a/lua/image/image.lua +++ b/lua/image/image.lua @@ -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 @@ -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 @@ -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 @@ -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, diff --git a/lua/image/renderer.lua b/lua/image/renderer.lua index e433e0b..e2929a5 100644 --- a/lua/image/renderer.lua +++ b/lua/image/renderer.lua @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -364,7 +386,14 @@ 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() @@ -372,7 +401,7 @@ local render = function(image) 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 @@ -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 diff --git a/lua/types.lua b/lua/types.lua index 18e9df7..96127ad 100644 --- a/lua/types.lua +++ b/lua/types.lua @@ -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)