Skip to content

Commit f3461ab

Browse files
committed
2 parents 7a31fbd + a37c565 commit f3461ab

File tree

6 files changed

+87
-38
lines changed

6 files changed

+87
-38
lines changed

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
# Changelog
22

3+
## Image 0.62.1
4+
5+
This is the changelog for Image version 0.62.1 released on October 23rd, 2025. For older changelogs please consult the release tag on [GitHub](https://github.com/elixir-image/image/tags)
6+
7+
### Bug Fixes
8+
9+
* Fix decoding EXIF component configuration if the value is invalid. Fixes #194. Thanks to @ethangunderson for the report.
10+
11+
* Fix `Image.minimize_metadata/1` when the image does not have an author or copyright field.
12+
313
## Image 0.62.0
414

515
This is the changelog for Image version 0.62.0 released on August 8th, 2025. For older changelogs please consult the release tag on [GitHub](https://github.com/elixir-image/image/tags)

lib/image.ex

Lines changed: 39 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1084,18 +1084,18 @@ defmodule Image do
10841084
* `options` is a keyword list of options. See `Image.open/2`
10851085
for the list of applicable options.
10861086
1087-
### Notes
1088-
1089-
This function is typically *not* the best way to open
1090-
an image. It requires that the entire image
1091-
is already loaded into memory which, for most use cases,
1092-
doest not scale well and consumes far more memory than
1093-
necessary.
1094-
1095-
Since `libvips` is a streaming on-demand architecture,
1096-
it is most likely that a simple `Image.open/2` call will
1097-
deliver better resource utilitsation and equal or better
1098-
performance.
1087+
> #### Note {: .info}
1088+
>
1089+
> This function is typically *not* the best way to open
1090+
> an image. It requires that the entire image
1091+
> is already loaded into memory which, for most use cases,
1092+
> doest not scale well and consumes far more memory than
1093+
> necessary.
1094+
>
1095+
> Since `libvips` is a streaming on-demand architecture,
1096+
> it is most likely that a simple `Image.open/2` call will
1097+
> deliver better resource utilitsation and equal or better
1098+
> performance.
10991099
11001100
### Returns
11011101
@@ -6337,16 +6337,19 @@ defmodule Image do
63376337
with intellectual property concerns in mind
63386338
this function will keep the artist and
63396339
copyright fields if they exist in the original
6340-
image.
6340+
image EXIF. Creator/Author/Artist and Copyright in
6341+
other fields like IPTC and XMP are not considered
6342+
in the current implementation.
63416343
63426344
On a 1000x500px image exported from Adobe Lightroom
63436345
with metadata intact, removing the metadata
63446346
results in am approximately 50% saving in file
63456347
size due to the removal of most EXIF and all
63466348
IPTC and XMP metadata.
63476349
6348-
Note that the minimized metadata is only materialized when
6349-
the minimized image is saved to a file.
6350+
> #### Note {: .info}
6351+
>
6352+
> the minimized metadata is only materialized when the minimized image is saved.
63506353
63516354
### Arguments
63526355
@@ -6363,15 +6366,28 @@ defmodule Image do
63636366

63646367
@spec minimize_metadata(image :: Vimage.t()) :: {:ok, Vimage.t()} | {:error, error_message()}
63656368
def minimize_metadata(%Vimage{} = image) do
6366-
with {:ok, exif} <- exif(image),
6367-
{:ok, image} <- remove_metadata(image) do
6368-
Vimage.mutate(image, fn mut_img ->
6369-
:ok = Exif.put_metadata(mut_img, :copyright, exif.copyright)
6370-
:ok = Exif.put_metadata(mut_img, :artist, exif.artist)
6371-
end)
6369+
case exif(image) do
6370+
{:ok, exif} ->
6371+
image
6372+
|> remove_metadata!()
6373+
|> put_copyright_and_artist(exif)
6374+
6375+
{:error, "No such field"} ->
6376+
remove_metadata(image)
6377+
6378+
other ->
6379+
other
63726380
end
63736381
end
63746382

6383+
defp put_copyright_and_artist(image, exif) do
6384+
Vimage.mutate(image, fn mut_img ->
6385+
if exif[:copyright], do: Exif.put_metadata(mut_img, :copyright, exif[:copyright])
6386+
if exif[:artist], do: Exif.put_metadata(mut_img, :artist, exif[:artist])
6387+
:ok
6388+
end)
6389+
end
6390+
63756391
@doc """
63766392
Minimize metadata by keeping only the artist
63776393
and copyright (if available).
@@ -6437,7 +6453,7 @@ defmodule Image do
64376453
in an image can be returned with a call to
64386454
`Vix.Vips.Image.header_field_names/1`.
64396455
6440-
* Errors removing metadata fields is not propagated
6456+
* Errors removing metadata fields are not propagated
64416457
into the return for this function. Errors might occur
64426458
when attempting to remove metadata fields that
64436459
do not exist in the image.
@@ -6501,7 +6517,7 @@ defmodule Image do
65016517
in an image can be returned with a call to
65026518
`Vix.Vips.Image.header_field_names/1`.
65036519
6504-
* Errors removing metadata fields is not propagated
6520+
* Errors removing metadata fields are not propagated
65056521
into the return for this function. Errors might occur
65066522
when attempting to remove metadata fields that
65076523
do not exist in the image.

lib/image/exif/decode.ex

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -201,12 +201,16 @@ defmodule Image.Exif.Decode do
201201
@comp_conf {"-", "Y", "Cb", "Cr", "R", "G", "B"}
202202

203203
@spec component_configuration([non_neg_integer()]) :: binary()
204-
defp component_configuration(list) do
205-
list
204+
defp component_configuration(components) when is_list(components) do
205+
components
206206
|> Enum.map(&elem(@comp_conf, &1))
207207
|> Enum.join(",")
208208
end
209209

210+
defp component_configuration(components) do
211+
"Unknown #{inspect components}"
212+
end
213+
210214
@spec metering_mode(non_neg_integer()) :: binary()
211215
defp metering_mode(1), do: "Average"
212216
defp metering_mode(2), do: "Center-weighted average"

mix.exs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
defmodule Image.MixProject do
22
use Mix.Project
33

4-
@version "0.62.0"
4+
@version "0.62.1"
55

66
@app_name "image"
77

@@ -21,13 +21,21 @@ defmodule Image.MixProject do
2121
package: package(),
2222
aliases: aliases(),
2323
elixirc_paths: elixirc_paths(Mix.env()),
24-
preferred_cli_env: preferred_cli_env(),
2524
dialyzer: [
2625
ignore_warnings: ".dialyzer_ignore_warnings",
2726
plt_add_apps: ~w(mix nx plug evision bumblebee ex_unit)a
2827
],
2928
compilers: Mix.compilers()
3029
]
30+
|> Keyword.merge(maybe_add_preferred_cli())
31+
end
32+
33+
defp maybe_add_preferred_cli() do
34+
if Version.compare(System.version(), "1.19.0-dev") == :lt do
35+
[preferred_cli_env: cli()]
36+
else
37+
[]
38+
end
3139
end
3240

3341
defp description do
@@ -207,7 +215,8 @@ defmodule Image.MixProject do
207215
|> List.to_integer()
208216
end
209217

210-
defp preferred_cli_env() do
218+
@doc false
219+
def cli() do
211220
[]
212221
end
213222

0 commit comments

Comments
 (0)