You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Phoenix/Elixir中通过Waffle-Ecto Changeset调整图片尺寸后上传AWS

如何在Waffle-Ecto的Changeset中上传前用ImageMagick处理图片?

你的Schema代码如下:

defmodule App.Images.Image do
  use Ecto.Schema
  import Ecto.Changeset
  use Waffle.Ecto.Schema

  schema "images" do
    field(:image, App.ImageUploader.Type)
  end

  def changeset(listing, attrs) do
    listing
    |> cast_attachments(attrs, [:image])
  end
end

要实现上传前调整图片尺寸,核心是在Waffle上传器中定义转换逻辑,而非直接修改Changeset。具体步骤如下:

1. 添加依赖

在mix.exs中添加封装ImageMagick的mogrify库:

defp deps do
  [
    {:waffle, "~> 1.1"},
    {:waffle_ecto, "~> 0.0.11"},
    {:mogrify, "~> 0.9.3"},
    {:ex_aws, "~> 2.4"},
    {:ex_aws_s3, "~> 2.4"},
    {:hackney, "~> 1.18"},
    {:sweet_xml, "~> 0.7.3"}
  ]
end

执行mix deps.get安装依赖,同时确保服务器已安装ImageMagick(Ubuntu可执行apt install imagemagick,Mac用brew install imagemagick)。

2. 修改Waffle上传器

调整App.ImageUploader,通过transform/2方法实现图片尺寸转换:

defmodule App.ImageUploader do
  use Waffle.Definition
  use Waffle.Ecto.Definition

  @storage Waffle.Storage.S3

  # 验证允许的图片格式
  def validate({file, _}) do
    ext = file.file_name |> Path.extname() |> String.downcase()
    Enum.member?([".jpg", ".jpeg", ".png", ".gif"], ext)
  end

  # 上传前调整图片尺寸:保持宽高比,缩放到最大800x800
  def transform(:original, {file, _}) do
    with {:ok, img} <- Mogrify.open(file.path),
         {:ok, resized_img} <- Mogrify.resize(img, "800x800>") do
      {:ok, resized_img.path}
    else
      _ -> :skip # 转换失败时上传原文件,可根据需求改为抛出错误
    end
  end

  # 自定义文件名规则
  def filename(version, {file, _}) do
    "#{version}_#{Path.basename(file.file_name, Path.extname(file.file_name))}"
  end

  # S3存储目录
  def storage_dir(_version, {_file, _scope}) do
    "uploads/images"
  end
end

3. 调整Changeset(可选)

如果需要添加必填验证或其他规则,修改原Changeset:

def changeset(listing, attrs) do
  listing
  |> cast_attachments(attrs, [:image])
  |> validate_required([:image])
end

说明

  • transform/2会在文件上传到S3前触发,返回处理后的文件路径,Waffle自动上传处理后的版本
  • Mogrify.resize的参数"800x800>"表示保持宽高比,仅当图片超过800x800时才缩放
  • 若转换失败,当前逻辑会跳过转换直接上传原文件,可根据业务需求调整为抛出错误

内容的提问来源于stack exchange,提问作者mastari

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 15:10:21