gpt4 book ai didi

ruby-on-rails - 如何在 ruby​​ on rails 中将用户上传的图片转换为 webp

转载 作者:行者123 更新时间:2023-12-04 05:59:08 28 4
gpt4 key购买 nike

我想转换用户在 webp 中上传的图片以提高网站性能。我知道 webp 现在只支持两种浏览器,Google ChromeOpera

我正在使用 carrierwave 将图像上传到 s3

carrierwave 中没有找到任何支持将图像转换为 webp 的支持。

image-magick 有库 libwebp 可以将图像转换为 webp

rails 中有这样的 gem 吗?

我如何将图像转换为 carrierwave 并保存它。carrierwave 以外的解决方案也有效。

最佳答案

我有类似的任务,但没有上传到 S3。我用了webp-ffi gem 编写自定义转换器。

这是对我有帮助的解决方案。

首先你需要安装requirementswebp-ffi 的自述文件中指定 gem 。

之后添加 webp-ffi gem 到您的项目:

gem 'webp-ffi'

如果您不需要存储原始图像,您只需将自定义方法添加到您的 uploader 并使用 CarrierWave 的处理方法调用它。这是我将图像转换为 webp 格式的技巧:

class MyImageUploader < CarrierWave::Uploader::Base
storage :file

process convert_to_webp: [{ quality: 80, method: 5 }]

def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end

private

def convert_to_webp(options = {})
# Build path for new file
webp_path = "#{path}.webp"

# Encode (convert) image to webp format with passed options
WebP.encode(path, webp_path, options)

# HACK: Changing of this two instance variables is the only way
# I found to make CarrierWave save new file that was created
# by encoding original image.
@filename = webp_path.split('/').pop

@file = CarrierWave::SanitizedFile.new(
tempfile: webp_path,
filename: webp_path,
content_type: 'image/webp'
)
end
end

您可以将此方法移动到项目中的某个模块(确保它会正确地 autoload)。例如,我将此代码放在 app/services/web_p_converter.rb 中:

module WebPConverter
def convert_to_webp(options = {})
webp_path = "#{path}.webp"

WebP.encode(path, webp_path, options)

@filename = webp_path.split('/').pop

@file = CarrierWave::SanitizedFile.new(
tempfile: webp_path,
filename: webp_path,
content_type: 'image/webp'
)
end
end

现在我可以在每个需要 webp 转换的 uploader 中包含这个模块:

class MyImageUploader < CarrierWave::Uploader::Base
include WebPConverter

storage :file

process convert_to_webp: [{ quality: 80, method: 5 }]

def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
end

但是如果您需要存储文件的原始版本并在 uploader 中创建一个版本,您将需要使用这个 hack:

class MyImageUploader < CarrierWave::Uploader::Base
include WebPConverter

storage :file

version :webp do
process convert_to_webp: [{ quality: 80, method: 5 }]

def full_filename(file)
return "#{version_name}_#{filename}" if filename.split('.').last == 'webp'

"#{version_name}_#{file}.webp"
end
end

def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
end

必须这样做,因为 CarrierWave 使用原始图像名称来构建到其他版本的路径。

您还可以将逻辑从#full_filename 移动到一个方法中。例如,我将构建完整文件名的逻辑移到了 WebPConverter 模块中,因此它看起来像这样:

module WebPConverter
# ...

def build_webp_full_filename(filename, version_name)
return "#{version_name}_#{filename}" if filename.split('.').last == 'webp'

"#{version_name}_#{filename}.webp"
end
end

从现在开始,我可以将它用于需要转换为 webp 的版本:

class MyImageUploader < CarrierWave::Uploader::Base
include WebPConverter

storage :file

version :webp do
process convert_to_webp: [{ quality: 80, method: 5 }]

def full_filename(file)
build_webp_full_filename(file, version_name)
end
end

def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
end

结帐 carrierwave-webp我用作示例的 gem 来创建我对这个问题的解决方案(由于某种原因,这个 gem 对我不起作用)。

同时查看我的 simple app这是我用来演示工作解决方案的。

关于ruby-on-rails - 如何在 ruby​​ on rails 中将用户上传的图片转换为 webp,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49901480/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com