Include image format information
This commit is contained in:
parent
614bdc49b5
commit
801745a198
|
@ -1,8 +1,17 @@
|
||||||
syntax = "proto3";
|
syntax = "proto3";
|
||||||
|
|
||||||
|
enum Format {
|
||||||
|
WEBP = 0;
|
||||||
|
AVIF = 1;
|
||||||
|
JPG = 2;
|
||||||
|
PNG = 3;
|
||||||
|
GIF = 4;
|
||||||
|
}
|
||||||
|
|
||||||
message Image {
|
message Image {
|
||||||
bytes key = 1;
|
bytes key = 1;
|
||||||
string full_url = 2;
|
string full_url = 2;
|
||||||
string thumb_url = 3;
|
string thumb_url = 3;
|
||||||
string blurhash = 4;
|
string blurhash = 4;
|
||||||
|
Format format = 5;
|
||||||
}
|
}
|
||||||
|
|
20
src/main.rs
20
src/main.rs
|
@ -89,42 +89,44 @@ fn create(server: &str, args: CreateArgs) {
|
||||||
.inspect(|r| if r.is_ok() { print!("\x1b[32mDone!\n\x1b[37m├─\x1b[0m Thumbnailing... ") })
|
.inspect(|r| if r.is_ok() { print!("\x1b[32mDone!\n\x1b[37m├─\x1b[0m Thumbnailing... ") })
|
||||||
.inspect(|_| drop(stdout().flush()))
|
.inspect(|_| drop(stdout().flush()))
|
||||||
.map(|r| r.and_then(|(path, raw_dat)| {
|
.map(|r| r.and_then(|(path, raw_dat)| {
|
||||||
let (thumbnail, blurhash) = thumbnailing::thumbnail(&raw_dat)
|
let (full, thumbnail, blurhash, format) = thumbnailing::thumbnail(&raw_dat)
|
||||||
.map_err(|_| AviaryError::ImageFormatError(path.to_owned()))?;
|
.map_err(|_| AviaryError::ImageFormatError(path.to_owned()))?;
|
||||||
Ok((raw_dat, thumbnail, blurhash))
|
Ok((full.map(Either::Right).unwrap_or(Either::Left(raw_dat)), thumbnail, blurhash, format))
|
||||||
}))
|
}))
|
||||||
.inspect(|r| if r.is_ok() { print!("\x1b[32mDone!\n\x1b[37m├─\x1b[0m Encrypting... ")})
|
.inspect(|r| if r.is_ok() { print!("\x1b[32mDone!\n\x1b[37m├─\x1b[0m Encrypting... ")})
|
||||||
.inspect(|_| drop(stdout().flush()))
|
.inspect(|_| drop(stdout().flush()))
|
||||||
.map_ok(|(raw_dat, thumbnail, blurhash)| {
|
.map_ok(|(raw_dat, thumbnail, blurhash, format)| {
|
||||||
let key = crypto::make_key();
|
let key = crypto::make_key();
|
||||||
(
|
(
|
||||||
key,
|
key,
|
||||||
crypto::encrypt(&key, &raw_dat),
|
crypto::encrypt(&key, &raw_dat),
|
||||||
crypto::encrypt(&key, &thumbnail),
|
crypto::encrypt(&key, &thumbnail),
|
||||||
blurhash
|
blurhash,
|
||||||
|
format
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.inspect(|r| if r.is_ok() { print!("\x1b[32mDone!\n\x1b[37m└─\x1b[0m Uploading... ")})
|
.inspect(|r| if r.is_ok() { print!("\x1b[32mDone!\n\x1b[37m└─\x1b[0m Uploading... ")})
|
||||||
.inspect(|_| drop(stdout().flush()))
|
.inspect(|_| drop(stdout().flush()))
|
||||||
.map(|r| r.and_then(|(key, full_img, thumb, blurhash)|
|
.map(|r| r.and_then(|(key, full_img, thumb, blurhash, format)|
|
||||||
upload::put_data(&agent, server, &thumb)
|
upload::put_data(&agent, server, &thumb)
|
||||||
.and_then(|thumb_url|
|
.and_then(|thumb_url|
|
||||||
upload::put_data(&agent, server, &full_img)
|
upload::put_data(&agent, server, &full_img)
|
||||||
.map(|full_url| (key, full_url, thumb_url, blurhash)))
|
.map(|full_url| (key, full_url, thumb_url, blurhash, format)))
|
||||||
.map_err(AviaryError::from_upload_error)
|
.map_err(AviaryError::from_upload_error)
|
||||||
))
|
))
|
||||||
.map(|r| r.and_then(|(key, full_url, thumb_url, blurhash)| {
|
.map(|r| r.and_then(|(key, full_url, thumb_url, blurhash, format)| {
|
||||||
let full_trimmed = trim_url(server, &full_url);
|
let full_trimmed = trim_url(server, &full_url);
|
||||||
let thmb_trimmed = trim_url(server, &thumb_url);
|
let thmb_trimmed = trim_url(server, &thumb_url);
|
||||||
if let (Some(full_url), Some(thmb_url)) = (full_trimmed, thmb_trimmed) {
|
if let (Some(full_url), Some(thmb_url)) = (full_trimmed, thmb_trimmed) {
|
||||||
Ok((key, full_url.to_owned(), thmb_url.to_owned(), blurhash))
|
Ok((key, full_url.to_owned(), thmb_url.to_owned(), blurhash, format))
|
||||||
} else {
|
} else {
|
||||||
Err(AviaryError::ServerError(format!("Received bad response from server: {}", full_url)))
|
Err(AviaryError::ServerError(format!("Received bad response from server: {}", full_url)))
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
.inspect(|r| if r.is_ok() { println!("\x1b[32mDone!\n")})
|
.inspect(|r| if r.is_ok() { println!("\x1b[32mDone!\n")})
|
||||||
.map_ok(|(key, full_url, thumb_url, blurhash)| protobuf::image::Image {
|
.map_ok(|(key, full_url, thumb_url, blurhash, format)| protobuf::image::Image {
|
||||||
key: key.into(),
|
key: key.into(),
|
||||||
|
format: format.into(),
|
||||||
full_url, thumb_url, blurhash,
|
full_url, thumb_url, blurhash,
|
||||||
special_fields: Default::default()
|
special_fields: Default::default()
|
||||||
})
|
})
|
||||||
|
|
|
@ -37,6 +37,8 @@ pub struct Image {
|
||||||
pub thumb_url: ::std::string::String,
|
pub thumb_url: ::std::string::String,
|
||||||
// @@protoc_insertion_point(field:Image.blurhash)
|
// @@protoc_insertion_point(field:Image.blurhash)
|
||||||
pub blurhash: ::std::string::String,
|
pub blurhash: ::std::string::String,
|
||||||
|
// @@protoc_insertion_point(field:Image.format)
|
||||||
|
pub format: ::protobuf::EnumOrUnknown<Format>,
|
||||||
// special fields
|
// special fields
|
||||||
// @@protoc_insertion_point(special_field:Image.special_fields)
|
// @@protoc_insertion_point(special_field:Image.special_fields)
|
||||||
pub special_fields: ::protobuf::SpecialFields,
|
pub special_fields: ::protobuf::SpecialFields,
|
||||||
|
@ -54,7 +56,7 @@ impl Image {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData {
|
fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData {
|
||||||
let mut fields = ::std::vec::Vec::with_capacity(4);
|
let mut fields = ::std::vec::Vec::with_capacity(5);
|
||||||
let mut oneofs = ::std::vec::Vec::with_capacity(0);
|
let mut oneofs = ::std::vec::Vec::with_capacity(0);
|
||||||
fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>(
|
fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>(
|
||||||
"key",
|
"key",
|
||||||
|
@ -76,6 +78,11 @@ impl Image {
|
||||||
|m: &Image| { &m.blurhash },
|
|m: &Image| { &m.blurhash },
|
||||||
|m: &mut Image| { &mut m.blurhash },
|
|m: &mut Image| { &mut m.blurhash },
|
||||||
));
|
));
|
||||||
|
fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>(
|
||||||
|
"format",
|
||||||
|
|m: &Image| { &m.format },
|
||||||
|
|m: &mut Image| { &mut m.format },
|
||||||
|
));
|
||||||
::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<Image>(
|
::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<Image>(
|
||||||
"Image",
|
"Image",
|
||||||
fields,
|
fields,
|
||||||
|
@ -106,6 +113,9 @@ impl ::protobuf::Message for Image {
|
||||||
34 => {
|
34 => {
|
||||||
self.blurhash = is.read_string()?;
|
self.blurhash = is.read_string()?;
|
||||||
},
|
},
|
||||||
|
40 => {
|
||||||
|
self.format = is.read_enum_or_unknown()?;
|
||||||
|
},
|
||||||
tag => {
|
tag => {
|
||||||
::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?;
|
::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?;
|
||||||
},
|
},
|
||||||
|
@ -130,6 +140,9 @@ impl ::protobuf::Message for Image {
|
||||||
if !self.blurhash.is_empty() {
|
if !self.blurhash.is_empty() {
|
||||||
my_size += ::protobuf::rt::string_size(4, &self.blurhash);
|
my_size += ::protobuf::rt::string_size(4, &self.blurhash);
|
||||||
}
|
}
|
||||||
|
if self.format != ::protobuf::EnumOrUnknown::new(Format::WEBP) {
|
||||||
|
my_size += ::protobuf::rt::int32_size(5, self.format.value());
|
||||||
|
}
|
||||||
my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields());
|
my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields());
|
||||||
self.special_fields.cached_size().set(my_size as u32);
|
self.special_fields.cached_size().set(my_size as u32);
|
||||||
my_size
|
my_size
|
||||||
|
@ -148,6 +161,9 @@ impl ::protobuf::Message for Image {
|
||||||
if !self.blurhash.is_empty() {
|
if !self.blurhash.is_empty() {
|
||||||
os.write_string(4, &self.blurhash)?;
|
os.write_string(4, &self.blurhash)?;
|
||||||
}
|
}
|
||||||
|
if self.format != ::protobuf::EnumOrUnknown::new(Format::WEBP) {
|
||||||
|
os.write_enum(5, ::protobuf::EnumOrUnknown::value(&self.format))?;
|
||||||
|
}
|
||||||
os.write_unknown_fields(self.special_fields.unknown_fields())?;
|
os.write_unknown_fields(self.special_fields.unknown_fields())?;
|
||||||
::std::result::Result::Ok(())
|
::std::result::Result::Ok(())
|
||||||
}
|
}
|
||||||
|
@ -169,6 +185,7 @@ impl ::protobuf::Message for Image {
|
||||||
self.full_url.clear();
|
self.full_url.clear();
|
||||||
self.thumb_url.clear();
|
self.thumb_url.clear();
|
||||||
self.blurhash.clear();
|
self.blurhash.clear();
|
||||||
|
self.format = ::protobuf::EnumOrUnknown::new(Format::WEBP);
|
||||||
self.special_fields.clear();
|
self.special_fields.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,6 +195,7 @@ impl ::protobuf::Message for Image {
|
||||||
full_url: ::std::string::String::new(),
|
full_url: ::std::string::String::new(),
|
||||||
thumb_url: ::std::string::String::new(),
|
thumb_url: ::std::string::String::new(),
|
||||||
blurhash: ::std::string::String::new(),
|
blurhash: ::std::string::String::new(),
|
||||||
|
format: ::protobuf::EnumOrUnknown::from_i32(0),
|
||||||
special_fields: ::protobuf::SpecialFields::new(),
|
special_fields: ::protobuf::SpecialFields::new(),
|
||||||
};
|
};
|
||||||
&instance
|
&instance
|
||||||
|
@ -201,24 +219,107 @@ impl ::protobuf::reflect::ProtobufValue for Image {
|
||||||
type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>;
|
type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone,Copy,PartialEq,Eq,Debug,Hash)]
|
||||||
|
// @@protoc_insertion_point(enum:Format)
|
||||||
|
pub enum Format {
|
||||||
|
// @@protoc_insertion_point(enum_value:Format.WEBP)
|
||||||
|
WEBP = 0,
|
||||||
|
// @@protoc_insertion_point(enum_value:Format.AVIF)
|
||||||
|
AVIF = 1,
|
||||||
|
// @@protoc_insertion_point(enum_value:Format.JPG)
|
||||||
|
JPG = 2,
|
||||||
|
// @@protoc_insertion_point(enum_value:Format.PNG)
|
||||||
|
PNG = 3,
|
||||||
|
// @@protoc_insertion_point(enum_value:Format.GIF)
|
||||||
|
GIF = 4,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ::protobuf::Enum for Format {
|
||||||
|
const NAME: &'static str = "Format";
|
||||||
|
|
||||||
|
fn value(&self) -> i32 {
|
||||||
|
*self as i32
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_i32(value: i32) -> ::std::option::Option<Format> {
|
||||||
|
match value {
|
||||||
|
0 => ::std::option::Option::Some(Format::WEBP),
|
||||||
|
1 => ::std::option::Option::Some(Format::AVIF),
|
||||||
|
2 => ::std::option::Option::Some(Format::JPG),
|
||||||
|
3 => ::std::option::Option::Some(Format::PNG),
|
||||||
|
4 => ::std::option::Option::Some(Format::GIF),
|
||||||
|
_ => ::std::option::Option::None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const VALUES: &'static [Format] = &[
|
||||||
|
Format::WEBP,
|
||||||
|
Format::AVIF,
|
||||||
|
Format::JPG,
|
||||||
|
Format::PNG,
|
||||||
|
Format::GIF,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ::protobuf::EnumFull for Format {
|
||||||
|
fn enum_descriptor() -> ::protobuf::reflect::EnumDescriptor {
|
||||||
|
static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::Lazy::new();
|
||||||
|
descriptor.get(|| file_descriptor().enum_by_package_relative_name("Format").unwrap()).clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn descriptor(&self) -> ::protobuf::reflect::EnumValueDescriptor {
|
||||||
|
let index = *self as usize;
|
||||||
|
Self::enum_descriptor().value_by_index(index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ::std::default::Default for Format {
|
||||||
|
fn default() -> Self {
|
||||||
|
Format::WEBP
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Format {
|
||||||
|
fn generated_enum_descriptor_data() -> ::protobuf::reflect::GeneratedEnumDescriptorData {
|
||||||
|
::protobuf::reflect::GeneratedEnumDescriptorData::new::<Format>("Format")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static file_descriptor_proto_data: &'static [u8] = b"\
|
static file_descriptor_proto_data: &'static [u8] = b"\
|
||||||
\n\x0bimage.proto\"m\n\x05Image\x12\x10\n\x03key\x18\x01\x20\x01(\x0cR\
|
\n\x0bimage.proto\"\x8e\x01\n\x05Image\x12\x10\n\x03key\x18\x01\x20\x01(\
|
||||||
\x03key\x12\x19\n\x08full_url\x18\x02\x20\x01(\tR\x07fullUrl\x12\x1b\n\t\
|
\x0cR\x03key\x12\x19\n\x08full_url\x18\x02\x20\x01(\tR\x07fullUrl\x12\
|
||||||
thumb_url\x18\x03\x20\x01(\tR\x08thumbUrl\x12\x1a\n\x08blurhash\x18\x04\
|
\x1b\n\tthumb_url\x18\x03\x20\x01(\tR\x08thumbUrl\x12\x1a\n\x08blurhash\
|
||||||
\x20\x01(\tR\x08blurhashJ\x86\x02\n\x06\x12\x04\0\0\x07\x01\n\x08\n\x01\
|
\x18\x04\x20\x01(\tR\x08blurhash\x12\x1f\n\x06format\x18\x05\x20\x01(\
|
||||||
\x0c\x12\x03\0\0\x12\n\n\n\x02\x04\0\x12\x04\x02\0\x07\x01\n\n\n\x03\x04\
|
\x0e2\x07.FormatR\x06format*7\n\x06Format\x12\x08\n\x04WEBP\x10\0\x12\
|
||||||
\0\x01\x12\x03\x02\x08\r\n\x0b\n\x04\x04\0\x02\0\x12\x03\x03\x08\x16\n\
|
\x08\n\x04AVIF\x10\x01\x12\x07\n\x03JPG\x10\x02\x12\x07\n\x03PNG\x10\x03\
|
||||||
\x0c\n\x05\x04\0\x02\0\x05\x12\x03\x03\x08\r\n\x0c\n\x05\x04\0\x02\0\x01\
|
\x12\x07\n\x03GIF\x10\x04J\xa2\x04\n\x06\x12\x04\0\0\x10\x01\n\x08\n\x01\
|
||||||
\x12\x03\x03\x0e\x11\n\x0c\n\x05\x04\0\x02\0\x03\x12\x03\x03\x14\x15\n\
|
\x0c\x12\x03\0\0\x12\n\n\n\x02\x05\0\x12\x04\x02\0\x08\x01\n\n\n\x03\x05\
|
||||||
\x0b\n\x04\x04\0\x02\x01\x12\x03\x04\x08\x1c\n\x0c\n\x05\x04\0\x02\x01\
|
\0\x01\x12\x03\x02\x05\x0b\n\x0b\n\x04\x05\0\x02\0\x12\x03\x03\x08\x11\n\
|
||||||
\x05\x12\x03\x04\x08\x0e\n\x0c\n\x05\x04\0\x02\x01\x01\x12\x03\x04\x0f\
|
\x0c\n\x05\x05\0\x02\0\x01\x12\x03\x03\x08\x0c\n\x0c\n\x05\x05\0\x02\0\
|
||||||
\x17\n\x0c\n\x05\x04\0\x02\x01\x03\x12\x03\x04\x1a\x1b\n\x0b\n\x04\x04\0\
|
\x02\x12\x03\x03\x0f\x10\n\x0b\n\x04\x05\0\x02\x01\x12\x03\x04\x08\x11\n\
|
||||||
\x02\x02\x12\x03\x05\x08\x1d\n\x0c\n\x05\x04\0\x02\x02\x05\x12\x03\x05\
|
\x0c\n\x05\x05\0\x02\x01\x01\x12\x03\x04\x08\x0c\n\x0c\n\x05\x05\0\x02\
|
||||||
\x08\x0e\n\x0c\n\x05\x04\0\x02\x02\x01\x12\x03\x05\x0f\x18\n\x0c\n\x05\
|
\x01\x02\x12\x03\x04\x0f\x10\n\x0b\n\x04\x05\0\x02\x02\x12\x03\x05\x08\
|
||||||
\x04\0\x02\x02\x03\x12\x03\x05\x1b\x1c\n\x0b\n\x04\x04\0\x02\x03\x12\x03\
|
\x10\n\x0c\n\x05\x05\0\x02\x02\x01\x12\x03\x05\x08\x0b\n\x0c\n\x05\x05\0\
|
||||||
\x06\x08\x1c\n\x0c\n\x05\x04\0\x02\x03\x05\x12\x03\x06\x08\x0e\n\x0c\n\
|
\x02\x02\x02\x12\x03\x05\x0e\x0f\n\x0b\n\x04\x05\0\x02\x03\x12\x03\x06\
|
||||||
\x05\x04\0\x02\x03\x01\x12\x03\x06\x0f\x17\n\x0c\n\x05\x04\0\x02\x03\x03\
|
\x08\x10\n\x0c\n\x05\x05\0\x02\x03\x01\x12\x03\x06\x08\x0b\n\x0c\n\x05\
|
||||||
\x12\x03\x06\x1a\x1bb\x06proto3\
|
\x05\0\x02\x03\x02\x12\x03\x06\x0e\x0f\n\x0b\n\x04\x05\0\x02\x04\x12\x03\
|
||||||
|
\x07\x08\x10\n\x0c\n\x05\x05\0\x02\x04\x01\x12\x03\x07\x08\x0b\n\x0c\n\
|
||||||
|
\x05\x05\0\x02\x04\x02\x12\x03\x07\x0e\x0f\n\n\n\x02\x04\0\x12\x04\n\0\
|
||||||
|
\x10\x01\n\n\n\x03\x04\0\x01\x12\x03\n\x08\r\n\x0b\n\x04\x04\0\x02\0\x12\
|
||||||
|
\x03\x0b\x08\x16\n\x0c\n\x05\x04\0\x02\0\x05\x12\x03\x0b\x08\r\n\x0c\n\
|
||||||
|
\x05\x04\0\x02\0\x01\x12\x03\x0b\x0e\x11\n\x0c\n\x05\x04\0\x02\0\x03\x12\
|
||||||
|
\x03\x0b\x14\x15\n\x0b\n\x04\x04\0\x02\x01\x12\x03\x0c\x08\x1c\n\x0c\n\
|
||||||
|
\x05\x04\0\x02\x01\x05\x12\x03\x0c\x08\x0e\n\x0c\n\x05\x04\0\x02\x01\x01\
|
||||||
|
\x12\x03\x0c\x0f\x17\n\x0c\n\x05\x04\0\x02\x01\x03\x12\x03\x0c\x1a\x1b\n\
|
||||||
|
\x0b\n\x04\x04\0\x02\x02\x12\x03\r\x08\x1d\n\x0c\n\x05\x04\0\x02\x02\x05\
|
||||||
|
\x12\x03\r\x08\x0e\n\x0c\n\x05\x04\0\x02\x02\x01\x12\x03\r\x0f\x18\n\x0c\
|
||||||
|
\n\x05\x04\0\x02\x02\x03\x12\x03\r\x1b\x1c\n\x0b\n\x04\x04\0\x02\x03\x12\
|
||||||
|
\x03\x0e\x08\x1c\n\x0c\n\x05\x04\0\x02\x03\x05\x12\x03\x0e\x08\x0e\n\x0c\
|
||||||
|
\n\x05\x04\0\x02\x03\x01\x12\x03\x0e\x0f\x17\n\x0c\n\x05\x04\0\x02\x03\
|
||||||
|
\x03\x12\x03\x0e\x1a\x1b\n\x0b\n\x04\x04\0\x02\x04\x12\x03\x0f\x08\x1a\n\
|
||||||
|
\x0c\n\x05\x04\0\x02\x04\x06\x12\x03\x0f\x08\x0e\n\x0c\n\x05\x04\0\x02\
|
||||||
|
\x04\x01\x12\x03\x0f\x0f\x15\n\x0c\n\x05\x04\0\x02\x04\x03\x12\x03\x0f\
|
||||||
|
\x18\x19b\x06proto3\
|
||||||
";
|
";
|
||||||
|
|
||||||
/// `FileDescriptorProto` object which was a source for this generated file
|
/// `FileDescriptorProto` object which was a source for this generated file
|
||||||
|
@ -238,7 +339,8 @@ pub fn file_descriptor() -> &'static ::protobuf::reflect::FileDescriptor {
|
||||||
let mut deps = ::std::vec::Vec::with_capacity(0);
|
let mut deps = ::std::vec::Vec::with_capacity(0);
|
||||||
let mut messages = ::std::vec::Vec::with_capacity(1);
|
let mut messages = ::std::vec::Vec::with_capacity(1);
|
||||||
messages.push(Image::generated_message_descriptor_data());
|
messages.push(Image::generated_message_descriptor_data());
|
||||||
let mut enums = ::std::vec::Vec::with_capacity(0);
|
let mut enums = ::std::vec::Vec::with_capacity(1);
|
||||||
|
enums.push(Format::generated_enum_descriptor_data());
|
||||||
::protobuf::reflect::GeneratedFileDescriptor::new_generated(
|
::protobuf::reflect::GeneratedFileDescriptor::new_generated(
|
||||||
file_descriptor_proto(),
|
file_descriptor_proto(),
|
||||||
deps,
|
deps,
|
||||||
|
|
|
@ -1,11 +1,15 @@
|
||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
use image::{io::Reader, DynamicImage, ImageResult};
|
use image::{io::Reader, DynamicImage, ImageResult, ImageFormat};
|
||||||
use webp::{Encoder, WebPMemory};
|
use webp::{Encoder, WebPMemory};
|
||||||
|
|
||||||
pub fn thumbnail(bytes: &[u8]) -> ImageResult<(WebPMemory, String)> {
|
use crate::protobuf::image::Format;
|
||||||
let original_image = Reader::new(Cursor::new(bytes))
|
|
||||||
.with_guessed_format().expect("IO errors impossible with Cursor")
|
pub fn thumbnail(bytes: &[u8]) -> ImageResult<(Option<WebPMemory>, WebPMemory, String, Format)> {
|
||||||
.decode()?;
|
let original_image_encoded = Reader::new(Cursor::new(bytes))
|
||||||
|
.with_guessed_format().expect("IO errors impossible with Cursor");
|
||||||
|
let original_format = original_image_encoded.format();
|
||||||
|
let original_image = original_image_encoded.decode()?;
|
||||||
|
|
||||||
let new_dimm = u32::min(original_image.height(), original_image.width());
|
let new_dimm = u32::min(original_image.height(), original_image.width());
|
||||||
let crop_x = (original_image.width() - new_dimm) / 2;
|
let crop_x = (original_image.width() - new_dimm) / 2;
|
||||||
let crop_y = (original_image.height() - new_dimm) / 2;
|
let crop_y = (original_image.height() - new_dimm) / 2;
|
||||||
|
@ -15,11 +19,32 @@ pub fn thumbnail(bytes: &[u8]) -> ImageResult<(WebPMemory, String)> {
|
||||||
} else {
|
} else {
|
||||||
original_image.thumbnail_exact(400, 400)
|
original_image.thumbnail_exact(400, 400)
|
||||||
}.into_rgba8();
|
}.into_rgba8();
|
||||||
let blurhash = blurhash::encode(4, 4, 400, 400, scaled.as_raw());
|
let scale = scaled.width();
|
||||||
|
|
||||||
|
let blurhash = blurhash::encode(4, 4, scale, scale, scaled.as_raw());
|
||||||
|
|
||||||
|
let (recoded_original, format) = match original_format {
|
||||||
|
Some(ImageFormat::WebP) => (None, Format::WEBP),
|
||||||
|
Some(ImageFormat::Avif) => (None, Format::AVIF),
|
||||||
|
Some(ImageFormat::Jpeg) => (None, Format::JPG),
|
||||||
|
Some(ImageFormat::Png) => (None, Format::PNG),
|
||||||
|
Some(ImageFormat::Gif) => (None, Format::GIF),
|
||||||
|
_ => ( // Unrecognized or format which isn't spec-supported
|
||||||
|
Some(
|
||||||
|
Encoder::from_image(&original_image)
|
||||||
|
.expect("Error transcoding image as webp")
|
||||||
|
.encode_lossless(),
|
||||||
|
),
|
||||||
|
Format::WEBP
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
Ok((
|
Ok((
|
||||||
|
recoded_original,
|
||||||
Encoder::from_image(&DynamicImage::ImageRgba8(scaled))
|
Encoder::from_image(&DynamicImage::ImageRgba8(scaled))
|
||||||
.expect("Unexpected difficulty interpretting thumbnail")
|
.expect("Unexpected difficulty interpretting thumbnail")
|
||||||
.encode(50.0),
|
.encode(50.0),
|
||||||
blurhash
|
blurhash,
|
||||||
|
format,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue