* [NTG-context] Downsampling images (again) @ 2024-09-21 11:21 Henning Hraban Ramm 2024-09-21 14:30 ` [NTG-context] " Alan Braslau via ntg-context 2024-09-22 7:06 ` Peter Münster 0 siblings, 2 replies; 8+ messages in thread From: Henning Hraban Ramm @ 2024-09-21 11:21 UTC (permalink / raw) To: mailing list for ConTeXt users This is lying around for years, let’s try to get it finally working. The code below works, but doesn’t do the right thing. Since the original image doesn’t contain a resolution setting, gm doesn’t do anything: “gm convert: image does not contain resolution” It would be more reliable to use “gm convert -resize”, but for that we need to know the final pixel size. How can a converter function access … – the final (scaled) size of a placed image – the original pixel size of an image ? With that information it would be easy to calculate the target pixel size. And then it would be nice to hook this function into \setupexternalfigure[conversion=] """ \startluacode local function downsampler(oldname, newname, resolution) if not resolution or resolution == "" then resolution = 72 end local cmd = string.format( [[gm convert -resample %ix%i "%s" "%s"]], resolution, resolution, oldname, newname) logs.report("downsample", cmd) os.execute(cmd) end -- Set the PDF and default JPEG converters to the above function. figures.converters.jpg.pdf = downsampler figures.converters.jpg.default = downsampler \stopluacode \setupexternalfigure[ %conversion=downsampler,% not used resolution=10, ] \starttext \externalfigure[https://upload.wikimedia.org/wikipedia/commons/d/dd/Hermann_Zapf_signing.jpg][width=.5\textwidth] \stoptext """ Hraban ___________________________________________________________________________________ If your question is of interest to others as well, please add an entry to the Wiki! maillist : ntg-context@ntg.nl / https://mailman.ntg.nl/mailman3/lists/ntg-context.ntg.nl webpage : https://www.pragma-ade.nl / https://context.aanhet.net (mirror) archive : https://github.com/contextgarden/context wiki : https://wiki.contextgarden.net ___________________________________________________________________________________ ^ permalink raw reply [flat|nested] 8+ messages in thread
* [NTG-context] Re: Downsampling images (again) 2024-09-21 11:21 [NTG-context] Downsampling images (again) Henning Hraban Ramm @ 2024-09-21 14:30 ` Alan Braslau via ntg-context 2024-09-21 19:44 ` Henning Hraban Ramm 2024-09-22 7:06 ` Peter Münster 1 sibling, 1 reply; 8+ messages in thread From: Alan Braslau via ntg-context @ 2024-09-21 14:30 UTC (permalink / raw) To: Henning Hraban Ramm; +Cc: mailing list for ConTeXt users, Alan Braslau Hraban, I would first "fix" my image sources, individually, to contain missing resolution information. Alan On Sat, 21 Sep 2024 13:21:08 +0200 Henning Hraban Ramm <texml@fiee.net> wrote: > This is lying around for years, let’s try to get it finally working. > The code below works, but doesn’t do the right thing. > > Since the original image doesn’t contain a resolution setting, gm > doesn’t do anything: > “gm convert: image does not contain resolution” > > It would be more reliable to use “gm convert -resize”, but for that > we need to know the final pixel size. > > How can a converter function access … > – the final (scaled) size of a placed image > – the original pixel size of an image > ? > With that information it would be easy to calculate the target pixel > size. > > And then it would be nice to hook this function into > \setupexternalfigure[conversion=] > > > """ > \startluacode > local function downsampler(oldname, newname, resolution) > if not resolution or resolution == "" then > resolution = 72 > end > local cmd = string.format( > [[gm convert -resample %ix%i "%s" "%s"]], > resolution, resolution, oldname, newname) > logs.report("downsample", cmd) > os.execute(cmd) > end > > -- Set the PDF and default JPEG converters to the above function. > figures.converters.jpg.pdf = downsampler > figures.converters.jpg.default = downsampler > \stopluacode > > \setupexternalfigure[ > %conversion=downsampler,% not used > resolution=10, > ] > > \starttext > > \externalfigure[https://upload.wikimedia.org/wikipedia/commons/d/dd/Hermann_Zapf_signing.jpg][width=.5\textwidth] > > \stoptext > """ > > Hraban > ___________________________________________________________________________________ > If your question is of interest to others as well, please add an > entry to the Wiki! > > maillist : ntg-context@ntg.nl > / https://mailman.ntg.nl/mailman3/lists/ntg-context.ntg.nl webpage : https://www.pragma-ade.nl / https://context.aanhet.net (mirror) > archive : https://github.com/contextgarden/context > wiki : https://wiki.contextgarden.net > ___________________________________________________________________________________ ___________________________________________________________________________________ If your question is of interest to others as well, please add an entry to the Wiki! maillist : ntg-context@ntg.nl / https://mailman.ntg.nl/mailman3/lists/ntg-context.ntg.nl webpage : https://www.pragma-ade.nl / https://context.aanhet.net (mirror) archive : https://github.com/contextgarden/context wiki : https://wiki.contextgarden.net ___________________________________________________________________________________ ^ permalink raw reply [flat|nested] 8+ messages in thread
* [NTG-context] Re: Downsampling images (again) 2024-09-21 14:30 ` [NTG-context] " Alan Braslau via ntg-context @ 2024-09-21 19:44 ` Henning Hraban Ramm 2024-09-23 1:48 ` Alan Braslau via ntg-context 0 siblings, 1 reply; 8+ messages in thread From: Henning Hraban Ramm @ 2024-09-21 19:44 UTC (permalink / raw) To: mailing list for ConTeXt users Am 21.09.24 um 16:30 schrieb Alan Braslau: > I would first "fix" my image sources, individually, to contain missing > resolution information. The resolution setting is just metadata, it doesn’t affect pixel or file size. I need a function that works with “real” (pixel) sizes of images. Hraban ___________________________________________________________________________________ If your question is of interest to others as well, please add an entry to the Wiki! maillist : ntg-context@ntg.nl / https://mailman.ntg.nl/mailman3/lists/ntg-context.ntg.nl webpage : https://www.pragma-ade.nl / https://context.aanhet.net (mirror) archive : https://github.com/contextgarden/context wiki : https://wiki.contextgarden.net ___________________________________________________________________________________ ^ permalink raw reply [flat|nested] 8+ messages in thread
* [NTG-context] Re: Downsampling images (again) 2024-09-21 19:44 ` Henning Hraban Ramm @ 2024-09-23 1:48 ` Alan Braslau via ntg-context 0 siblings, 0 replies; 8+ messages in thread From: Alan Braslau via ntg-context @ 2024-09-23 1:48 UTC (permalink / raw) To: Henning Hraban Ramm; +Cc: mailing list for ConTeXt users, Alan Braslau On Sat, 21 Sep 2024 21:44:53 +0200 Henning Hraban Ramm <texml@fiee.net> wrote: > Am 21.09.24 um 16:30 schrieb Alan Braslau: > > I would first "fix" my image sources, individually, to contain > > missing resolution information. > > The resolution setting is just metadata, it doesn’t affect pixel or > file size. I need a function that works with “real” (pixel) sizes of > images. Exactly. The raw data is just pixels, and metadata sets what the expected pixel size might be. Of course, this metadata can be meaningless as the user can and often does rescale the image to meet the typesetting needs. The image manipulation tools use this metadata to resample resolution. I found this very useful as I used *hundreds* of scanned X-ray images that had real sizes, high resolution and 16 or even 24 bit depth. Of course, I had to reduce all of this in order to include them in a digestible and printable pdf. Alan ___________________________________________________________________________________ If your question is of interest to others as well, please add an entry to the Wiki! maillist : ntg-context@ntg.nl / https://mailman.ntg.nl/mailman3/lists/ntg-context.ntg.nl webpage : https://www.pragma-ade.nl / https://context.aanhet.net (mirror) archive : https://github.com/contextgarden/context wiki : https://wiki.contextgarden.net ___________________________________________________________________________________ ^ permalink raw reply [flat|nested] 8+ messages in thread
* [NTG-context] Re: Downsampling images (again) 2024-09-21 11:21 [NTG-context] Downsampling images (again) Henning Hraban Ramm 2024-09-21 14:30 ` [NTG-context] " Alan Braslau via ntg-context @ 2024-09-22 7:06 ` Peter Münster 2024-10-09 16:52 ` Henning Hraban Ramm 2024-10-16 17:59 ` Henning Hraban Ramm 1 sibling, 2 replies; 8+ messages in thread From: Peter Münster @ 2024-09-22 7:06 UTC (permalink / raw) To: ntg-context [-- Attachment #1: Type: text/plain, Size: 310 bytes --] On Sat, Sep 21 2024, Henning Hraban Ramm wrote: > How can a converter function access … > – the final (scaled) size of a placed image Hi, I use "figures.current().request" in my module (here attached). > – the original pixel size of an image ? I use img.scan() for that. HTH, -- Peter [-- Attachment #2: grph-downsample.lua --] [-- Type: application/octet-stream, Size: 1610 bytes --] if not modules then modules = { } end modules ['grph-downsample'] = { version = 1.001, comment = "companion to grph-inc.mkiv", author = "Peter Münster", copyright = "PRAGMA ADE / ConTeXt Development Team", license = "see context related readme files" } local format = string.format -- figures.cachepaths.path = "cache" -- should be setup-option local function sample_down(oldname, newname, resolution) local request = figures.current().request local width = request.width local height = request.height if resolution == "" or (not width and not height) then print(format("Nothing to do: %s, %s, %s", oldname, newname, resolution)) return end local inch = 72.27 local image = img.scan{filename = oldname} local xy = image.xsize / image.ysize if not width then width = height * xy / 65536 end if not height then height = width / xy / 65536 end local xsize = resolution * width / inch local ysize = resolution * height / inch if xsize < image.xsize or ysize < image.ysize then local s = format("gm convert -resize %dx%d %s %s", xsize, ysize, oldname, newname) print("Conversion: " .. s) os.execute(s) else print(format("Nothing to do: %s, %s, %s", oldname, newname, resolution)) print(format("xsize = %d, ysize = %d", xsize, ysize)) end end local formats = {"png", "jpg", "gif"} for _, s in ipairs(formats) do figures.converters[s] = figures.converters[s] or {} figures.converters[s]["lowres." .. s] = sample_down end [-- Attachment #3: Type: text/plain, Size: 511 bytes --] ___________________________________________________________________________________ If your question is of interest to others as well, please add an entry to the Wiki! maillist : ntg-context@ntg.nl / https://mailman.ntg.nl/mailman3/lists/ntg-context.ntg.nl webpage : https://www.pragma-ade.nl / https://context.aanhet.net (mirror) archive : https://github.com/contextgarden/context wiki : https://wiki.contextgarden.net ___________________________________________________________________________________ ^ permalink raw reply [flat|nested] 8+ messages in thread
* [NTG-context] Re: Downsampling images (again) 2024-09-22 7:06 ` Peter Münster @ 2024-10-09 16:52 ` Henning Hraban Ramm 2024-10-16 17:59 ` Henning Hraban Ramm 1 sibling, 0 replies; 8+ messages in thread From: Henning Hraban Ramm @ 2024-10-09 16:52 UTC (permalink / raw) To: mailing list for ConTeXt users Am 22.09.24 um 09:06 schrieb Peter Münster: > On Sat, Sep 21 2024, Henning Hraban Ramm wrote: > >> How can a converter function access … >> – the final (scaled) size of a placed image > > Hi, > > I use "figures.current().request" in my module (here attached). > > >> – the original pixel size of an image ? > > I use img.scan() for that. Hi Peter, sorry, I forgot to answer. I was using your code for years, and AFAIR it also doesn’t use the final scaled size. But I must check again – too much going on ATM… Hraban ___________________________________________________________________________________ If your question is of interest to others as well, please add an entry to the Wiki! maillist : ntg-context@ntg.nl / https://mailman.ntg.nl/mailman3/lists/ntg-context.ntg.nl webpage : https://www.pragma-ade.nl / https://context.aanhet.net (mirror) archive : https://github.com/contextgarden/context wiki : https://wiki.contextgarden.net ___________________________________________________________________________________ ^ permalink raw reply [flat|nested] 8+ messages in thread
* [NTG-context] Re: Downsampling images (again) 2024-09-22 7:06 ` Peter Münster 2024-10-09 16:52 ` Henning Hraban Ramm @ 2024-10-16 17:59 ` Henning Hraban Ramm 2024-10-17 11:11 ` Peter Münster 1 sibling, 1 reply; 8+ messages in thread From: Henning Hraban Ramm @ 2024-10-16 17:59 UTC (permalink / raw) To: ntg-context [-- Attachment #1: Type: text/plain, Size: 1192 bytes --] Am 22.09.24 um 09:06 schrieb Peter Münster: > On Sat, Sep 21 2024, Henning Hraban Ramm wrote: > >> How can a converter function access … >> – the final (scaled) size of a placed image > > Hi, > > I use "figures.current().request" in my module (here attached). > > >> – the original pixel size of an image ? > > I use img.scan() for that. Hi Peter, are you sure that your code works with LMTX? Find attached my version. It seems to work, but only for the first instance of an image, not for different sizes of the same image – makes sense WRT efficiency, but might give wrong results for some uses. Here’s my test code: """ \loadluafile[grph-downsample.lua] \setupexternalfigure[ location={local,global,default}, conversion=lowres.jpg, resolution=20, ] \starttext \useexternalfigure[zapf][https://upload.wikimedia.org/wikipedia/commons/d/dd/Hermann_Zapf_signing.jpg] \useexternalfigure[lino][https://upload.wikimedia.org/wikipedia/commons/b/bd/Linotype-vorne-deutsches-museum.jpg] \externalfigure[zapf][width=.5tw] \externalfigure[lino][height=.3th] \externalfigure[zapf][height=.5th] \stoptext """ Hraban [-- Attachment #2: grph-downsample.lua --] [-- Type: text/plain, Size: 2811 bytes --] if not modules then modules = { } end modules ['grph-downsample'] = { version = 1.103, comment = "companion to grph-inc.mkiv", author = "Peter Münster", -- adapted to LMTX by Hraban copyright = "PRAGMA ADE / ConTeXt Development Team", license = "see context related readme files" } local format = string.format local report = logs.reporter("DOWNSAMPLE") local function sample_down(oldname, newname, resolution) report("sample_down %s to %s (%s)", oldname, newname, resolution) local request = figures.current().request -- this is probably the original pixel size local width = request.width local height = request.height -- width/height are integer in sp or a boolean local TEXpt = 65536 local inch = 72.27 if resolution == "" then -- or (not width and not height) then report("Nothing to do (missing resolution): %s, %s, %s dpi, %s x %s px", oldname, newname, resolution, width, height) return else report("Requested: %s, %s, %s dpi, %s x %s px", oldname, newname, resolution, width, height) end -- MkIV: -- local image = img.scan{filename = oldname} -- LMTX: local image = figures.getinfo(oldname,1) image = image.status.private local xy = image.xsize / image.ysize -- size ratio if (not width and not height) then -- no size requested? use default width -- probably wrong… width = 300 * TEXpt end if not width then height = height / TEXpt width = height * xy end if not height then width = width / TEXpt height = width / xy end width = math.floor(width) height = math.floor(height) report("image size %dx%dpx. requested %dx%dpt at %ddpi.", image.xsize, image.ysize, width, height, resolution) local xsize = math.floor(resolution * width / inch) local ysize = math.floor(resolution * height / inch) report("resize %dx%dpx to %dx%dpx:", image.xsize, image.ysize, xsize, ysize) if xsize < image.xsize or ysize < image.ysize then -- maybe add a tolerance of 20% (don’t downsample if the difference is marginal) local s = format("gm convert -resize %dx%d -resample %dx%d \"%s\" \"%s\"", xsize, ysize, resolution, resolution, oldname, newname) report("calling: %s", s) os.execute(s) else report("Nothing to do (image smaller than requested): %s, %s, %s dpi, %d x %d px", oldname, newname, resolution, width, height) report("xsize = %d, ysize = %d", xsize, ysize) end end local formats = {"png", "jpg", "gif"} for _, s in ipairs(formats) do figures.converters[s] = figures.converters[s] or {} -- use \setupexternalfigure[conversion=lowres.jpg]: figures.converters[s]["lowres." .. s] = sample_down -- use without setup: --figures.converters[s].default = sample_down --figures.converters[s].pdf = sample_down -- gets used end [-- Attachment #3: Type: text/plain, Size: 511 bytes --] ___________________________________________________________________________________ If your question is of interest to others as well, please add an entry to the Wiki! maillist : ntg-context@ntg.nl / https://mailman.ntg.nl/mailman3/lists/ntg-context.ntg.nl webpage : https://www.pragma-ade.nl / https://context.aanhet.net (mirror) archive : https://github.com/contextgarden/context wiki : https://wiki.contextgarden.net ___________________________________________________________________________________ ^ permalink raw reply [flat|nested] 8+ messages in thread
* [NTG-context] Re: Downsampling images (again) 2024-10-16 17:59 ` Henning Hraban Ramm @ 2024-10-17 11:11 ` Peter Münster 0 siblings, 0 replies; 8+ messages in thread From: Peter Münster @ 2024-10-17 11:11 UTC (permalink / raw) To: ntg-context [-- Attachment #1: Type: text/plain, Size: 549 bytes --] On Wed, Oct 16 2024, Henning Hraban Ramm wrote: >> I use img.scan() for that. > > are you sure that your code works with LMTX? Hi Hraban, No, sorry, I didn’t test it... > Find attached my version. Thanks, I have integrated your ideas in a new version here attached. > It seems to work, but only for the first instance of an image, Yes, you need to patch the file grph-inc.lmt: https://lists.contextgarden.net/archives/list/ntg-context@ntg.nl/message/ES7Q57MU5UIEV2B2AWEAPR66MMXI6ZHY/ Cheers, -- Peter [-- Attachment #2: grph-downsample.lua --] [-- Type: application/octet-stream, Size: 2299 bytes --] if not modules then modules = { } end modules ['grph-downsample'] = { version = 1.104, comment = "companion to grph-inc.mkiv", author = "Peter Münster and Henning Hraban Ramm", copyright = "PRAGMA ADE / ConTeXt Development Team", license = "see context related readme files" } -- todo: -- figures.cachepaths.path = "cache" -- should be a setup-option -- threshold should be a setup-option local function round(x) return math.floor(x + 0.5) end local format = string.format local report = logs.reporter("DOWNSAMPLE") local function sample_down(oldname, newname, resolution) report("sample_down %s to %s (%s)", oldname, newname, resolution) local request = figures.current().request local width = request.width local height = request.height if resolution == "" or (not width and not height) then report("Nothing to do: %s, %s, %s", oldname, newname, resolution) return else report("Requested: %s, %s, %s dpi, %s sp x %s sp", oldname, newname, resolution, width or "???", height or "???") end -- requested size must be smaller than original size -- multiplied by this threshold: local threshold = 0.8 local inch = 72.27 * 65536 -- an inch in scaled points local image = figures.getinfo(oldname, 1) image = image.status.private local xy = image.xsize / image.ysize if not width then width = height * xy end if not height then height = width / xy end local xsize = round(resolution * width / inch) local ysize = round(resolution * height / inch) report("resize %d x %d to %d x %d:", image.xsize, image.ysize, xsize, ysize) if xsize < image.xsize * threshold or ysize < image.ysize * threshold then local s = format("gm convert -resize %dx%d %s %s", xsize, ysize, oldname, newname) report("calling: %s", s) os.execute(s) else report("Nothing to do: %s, %s, %s", oldname, newname, resolution) report("xsize = %d, ysize = %d", xsize, ysize) end end local formats = {"png", "jpg", "gif"} for _, s in ipairs(formats) do figures.converters[s] = figures.converters[s] or {} figures.converters[s]["lowres." .. s] = sample_down end [-- Attachment #3: Type: text/plain, Size: 511 bytes --] ___________________________________________________________________________________ If your question is of interest to others as well, please add an entry to the Wiki! maillist : ntg-context@ntg.nl / https://mailman.ntg.nl/mailman3/lists/ntg-context.ntg.nl webpage : https://www.pragma-ade.nl / https://context.aanhet.net (mirror) archive : https://github.com/contextgarden/context wiki : https://wiki.contextgarden.net ___________________________________________________________________________________ ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2024-10-17 11:21 UTC | newest] Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2024-09-21 11:21 [NTG-context] Downsampling images (again) Henning Hraban Ramm 2024-09-21 14:30 ` [NTG-context] " Alan Braslau via ntg-context 2024-09-21 19:44 ` Henning Hraban Ramm 2024-09-23 1:48 ` Alan Braslau via ntg-context 2024-09-22 7:06 ` Peter Münster 2024-10-09 16:52 ` Henning Hraban Ramm 2024-10-16 17:59 ` Henning Hraban Ramm 2024-10-17 11:11 ` Peter Münster
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).