FEATURE: Support converting HEIF images to JPEG (#10079)

This commit is contained in:
Penar Musaraj 2020-07-22 21:40:09 -04:00 committed by GitHub
parent 10a6824e5f
commit 7559758e10
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 53 additions and 0 deletions

View File

@ -1763,6 +1763,7 @@ en:
png_to_jpg_quality: "Quality of the converted JPG file (1 is lowest quality, 99 is best quality, 100 to disable)." png_to_jpg_quality: "Quality of the converted JPG file (1 is lowest quality, 99 is best quality, 100 to disable)."
allow_staff_to_upload_any_file_in_pm: "Allow staff members to upload any files in PM." allow_staff_to_upload_any_file_in_pm: "Allow staff members to upload any files in PM."
convert_heif_to_jpeg: "Convert '.heic' or '.heif' image uploads to jpeg."
strip_image_metadata: "Strip image metadata." strip_image_metadata: "Strip image metadata."

View File

@ -1302,6 +1302,8 @@ files:
decompressed_backup_max_file_size_mb: decompressed_backup_max_file_size_mb:
default: 100000 default: 100000
hidden: true hidden: true
convert_heif_to_jpeg:
default: false
trust: trust:
default_trust_level: default_trust_level:

View File

@ -40,6 +40,12 @@ class UploadCreator
is_image = false if @opts[:for_theme] is_image = false if @opts[:for_theme]
DistributedMutex.synchronize("upload_#{user_id}_#{@filename}") do DistributedMutex.synchronize("upload_#{user_id}_#{@filename}") do
# We need to convert HEIFs early because FastImage does not consider them as images
if convert_heif_to_jpeg?
convert_heif!
is_image = FileHelper.is_supported_image?("test.#{@image_info.type}")
end
if is_image if is_image
extract_image_info! extract_image_info!
return @upload if @upload.errors.present? return @upload if @upload.errors.present?
@ -211,6 +217,28 @@ class UploadCreator
end end
end end
def convert_heif_to_jpeg?
SiteSetting.convert_heif_to_jpeg && File.extname(@filename).downcase.match?(/\.hei(f|c)$/)
end
def convert_heif!
jpeg_tempfile = Tempfile.new(["image", ".jpg"])
from = @file.path
to = jpeg_tempfile.path
OptimizedImage.ensure_safe_paths!(from, to)
begin
execute_convert(from, to)
rescue
# retry with debugging enabled
execute_convert(from, to, true)
end
@file.respond_to?(:close!) ? @file.close! : @file.close
@file = jpeg_tempfile
extract_image_info!
end
def execute_convert(from, to, debug = false) def execute_convert(from, to, debug = false)
command = [ command = [
"convert", "convert",

BIN
spec/fixtures/images/should_be_jpeg.heic vendored Normal file

Binary file not shown.

View File

@ -170,6 +170,28 @@ RSpec.describe UploadCreator do
end end
end end
describe 'converting HEIF to jpeg' do
let(:filename) { "should_be_jpeg.heic" }
let(:file) { file_from_fixtures(filename, "images") }
before do
SiteSetting.convert_heif_to_jpeg = true
SiteSetting.authorized_extensions = 'jpg|heic'
end
it 'should store the upload with the right extension' do
expect do
UploadCreator.new(file, filename).create_for(user.id)
end.to change { Upload.count }.by(1)
upload = Upload.last
expect(upload.extension).to eq('jpeg')
expect(File.extname(upload.url)).to eq('.jpeg')
expect(upload.original_filename).to eq('should_be_jpeg.jpg')
end
end
describe 'secure attachments' do describe 'secure attachments' do
let(:filename) { "small.pdf" } let(:filename) { "small.pdf" }
let(:file) { file_from_fixtures(filename, "pdf") } let(:file) { file_from_fixtures(filename, "pdf") }