lets generate some images
This commit is contained in:
parent
f1b3400e63
commit
7734c03ba5
27
axum_server/src/picture_generator/export_format.rs
Normal file
27
axum_server/src/picture_generator/export_format.rs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
|
||||||
|
#[derive(Debug, PartialEq)]
|
||||||
|
pub enum ExportFormat {
|
||||||
|
JPG,
|
||||||
|
AVIF,
|
||||||
|
SVG,
|
||||||
|
PNG,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ExportFormat {
|
||||||
|
pub fn get_extension(&self) -> &str {
|
||||||
|
match self {
|
||||||
|
ExportFormat::JPG => "jpg",
|
||||||
|
ExportFormat::AVIF => "avif",
|
||||||
|
ExportFormat::SVG => "svg",
|
||||||
|
ExportFormat::PNG => "png",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn get_type(&self) -> &str {
|
||||||
|
match self {
|
||||||
|
ExportFormat::JPG => "image/jpeg",
|
||||||
|
ExportFormat::AVIF => "image/avif",
|
||||||
|
ExportFormat::SVG => "image/svg+xml",
|
||||||
|
ExportFormat::PNG => "image/png",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -21,4 +21,5 @@ It can be used from the rust code
|
|||||||
It should be used from the templates as well
|
It should be used from the templates as well
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
pub mod export_format;
|
||||||
pub mod picture_markup_generator;
|
pub mod picture_markup_generator;
|
||||||
|
@ -1,41 +1,16 @@
|
|||||||
use std::{
|
use std::{
|
||||||
cmp::Ordering,
|
cmp::Ordering,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
str::FromStr,
|
str::FromStr as _,
|
||||||
};
|
};
|
||||||
|
|
||||||
use axum::handler::HandlerWithoutStateExt;
|
use anyhow::Context;
|
||||||
use image::{GenericImageView, ImageReader};
|
use image::{GenericImageView, ImageReader};
|
||||||
|
|
||||||
|
use super::export_format::ExportFormat;
|
||||||
|
|
||||||
pub const PIXEL_DENSITIES: [f32; 5] = [1., 1.5, 2., 3., 4.];
|
pub const PIXEL_DENSITIES: [f32; 5] = [1., 1.5, 2., 3., 4.];
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
|
||||||
pub enum ExportFormat {
|
|
||||||
JPG,
|
|
||||||
AVIF,
|
|
||||||
SVG,
|
|
||||||
PNG,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ExportFormat {
|
|
||||||
pub fn get_extension(&self) -> &str {
|
|
||||||
match self {
|
|
||||||
ExportFormat::JPG => "jpg",
|
|
||||||
ExportFormat::AVIF => "avif",
|
|
||||||
ExportFormat::SVG => "svg",
|
|
||||||
ExportFormat::PNG => "png",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn get_type(&self) -> &str {
|
|
||||||
match self {
|
|
||||||
ExportFormat::JPG => "image/jpeg",
|
|
||||||
ExportFormat::AVIF => "image/avif",
|
|
||||||
ExportFormat::SVG => "image/svg+xml",
|
|
||||||
ExportFormat::PNG => "image/png",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn generate_picture_markup(
|
pub fn generate_picture_markup(
|
||||||
orig_img_path: &str,
|
orig_img_path: &str,
|
||||||
width: u32,
|
width: u32,
|
||||||
@ -44,7 +19,13 @@ pub fn generate_picture_markup(
|
|||||||
) -> Result<String, anyhow::Error> {
|
) -> Result<String, anyhow::Error> {
|
||||||
let exported_formats = get_export_formats(orig_img_path);
|
let exported_formats = get_export_formats(orig_img_path);
|
||||||
let path_to_generated = get_generated_file_name(orig_img_path);
|
let path_to_generated = get_generated_file_name(orig_img_path);
|
||||||
let orig_img = ImageReader::open(orig_img_path)?.decode()?;
|
|
||||||
|
// TODO This should get removed when we move the project structure #move
|
||||||
|
let dev_only_img_path = Path::new("../static/").join(orig_img_path.strip_prefix("/").unwrap());
|
||||||
|
|
||||||
|
let orig_img = ImageReader::open(&dev_only_img_path)
|
||||||
|
.with_context(|| format!("Failed to read instrs from {:?}", &dev_only_img_path))?
|
||||||
|
.decode()?;
|
||||||
let orig_img_dimensions = orig_img.dimensions();
|
let orig_img_dimensions = orig_img.dimensions();
|
||||||
let resolutions = get_resolutions(orig_img_dimensions, width, height);
|
let resolutions = get_resolutions(orig_img_dimensions, width, height);
|
||||||
|
|
||||||
@ -221,20 +202,20 @@ fn get_generated_file_name(orig_img_path: &str) -> PathBuf {
|
|||||||
let file_name = path
|
let file_name = path
|
||||||
.file_stem()
|
.file_stem()
|
||||||
.expect("There should be a name for every img");
|
.expect("There should be a name for every img");
|
||||||
let result = Path::new("./generated_images/")
|
let result = Path::new("/generated_images/")
|
||||||
.join(parent)
|
.join(parent.strip_prefix("/").unwrap())
|
||||||
.join(file_name);
|
.join(file_name);
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_get_generated_paths() {
|
fn test_get_generated_paths() {
|
||||||
let orig_img_path = "./images/uploads/img_name.jpg";
|
let orig_img_path = "/images/uploads/img_name.jpg";
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
get_generated_file_name(orig_img_path)
|
get_generated_file_name(orig_img_path)
|
||||||
.to_str()
|
.to_str()
|
||||||
.unwrap_or(""),
|
.unwrap_or(""),
|
||||||
"./generated_images/images/uploads/img_name"
|
"/generated_images/images/uploads/img_name"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -271,13 +252,13 @@ fn get_export_formats(orig_img_path: &str) -> Vec<ExportFormat> {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_get_export_formats() {
|
fn test_get_export_formats() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
get_export_formats("./images/uploads/img_name.jpg"),
|
get_export_formats("/images/uploads/img_name.jpg"),
|
||||||
vec![ExportFormat::AVIF, ExportFormat::JPG]
|
vec![ExportFormat::AVIF, ExportFormat::JPG]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn test_generate_srcset() {
|
fn test_generate_srcset() {
|
||||||
let orig_img_path = PathBuf::from_str("./generated_images/images/uploads/img_name").unwrap();
|
let orig_img_path = PathBuf::from_str("/generated_images/images/uploads/img_name").unwrap();
|
||||||
let export_format = ExportFormat::AVIF;
|
let export_format = ExportFormat::AVIF;
|
||||||
let resolutions = vec![
|
let resolutions = vec![
|
||||||
(320, 200, 1.),
|
(320, 200, 1.),
|
||||||
@ -286,7 +267,7 @@ fn test_generate_srcset() {
|
|||||||
(960, 600, 3.),
|
(960, 600, 3.),
|
||||||
(1200, 750, 4.),
|
(1200, 750, 4.),
|
||||||
];
|
];
|
||||||
let result = "./generated_images/images/uploads/img_name_320x200.avif 1x, ./generated_images/images/uploads/img_name_480x300.avif 1.5x, ./generated_images/images/uploads/img_name_640x400.avif 2x, ./generated_images/images/uploads/img_name_960x600.avif 3x, ./generated_images/images/uploads/img_name_1200x750.avif 4x";
|
let result = "/generated_images/images/uploads/img_name_320x200.avif 1x, /generated_images/images/uploads/img_name_480x300.avif 1.5x, /generated_images/images/uploads/img_name_640x400.avif 2x, /generated_images/images/uploads/img_name_960x600.avif 3x, /generated_images/images/uploads/img_name_1200x750.avif 4x";
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
generate_srcset(&orig_img_path, &export_format, &resolutions),
|
generate_srcset(&orig_img_path, &export_format, &resolutions),
|
||||||
result
|
result
|
||||||
@ -297,18 +278,18 @@ fn test_generate_srcset() {
|
|||||||
fn test_generate_picture_markup() {
|
fn test_generate_picture_markup() {
|
||||||
let width = 300;
|
let width = 300;
|
||||||
let height = 200;
|
let height = 200;
|
||||||
let orig_img_path = "../static/images/uploads/2020-03-23_20-24-06_393.jpg";
|
let orig_img_path = "/images/uploads/2020-03-23_20-24-06_393.jpg";
|
||||||
let result = r#"<picture>
|
let result = r#"<picture>
|
||||||
<source
|
<source
|
||||||
srcset="./generated_images/static/images/uploads/2020-03-23_20-24-06_393_300x200.avif 1x, ./generated_images/static/images/uploads/2020-03-23_20-24-06_393_450x300.avif 1.5x, ./generated_images/static/images/uploads/2020-03-23_20-24-06_393_600x400.avif 2x, ./generated_images/static/images/uploads/2020-03-23_20-24-06_393_900x600.avif 3x, ./generated_images/static/images/uploads/2020-03-23_20-24-06_393_1200x800.avif 4x"
|
srcset="/generated_images/images/uploads/2020-03-23_20-24-06_393_300x200.avif 1x, /generated_images/images/uploads/2020-03-23_20-24-06_393_450x300.avif 1.5x, /generated_images/images/uploads/2020-03-23_20-24-06_393_600x400.avif 2x, /generated_images/images/uploads/2020-03-23_20-24-06_393_900x600.avif 3x, /generated_images/images/uploads/2020-03-23_20-24-06_393_1200x800.avif 4x"
|
||||||
type="image/avif"
|
type="image/avif"
|
||||||
>
|
>
|
||||||
<source
|
<source
|
||||||
srcset="./generated_images/static/images/uploads/2020-03-23_20-24-06_393_300x200.jpg 1x, ./generated_images/static/images/uploads/2020-03-23_20-24-06_393_450x300.jpg 1.5x, ./generated_images/static/images/uploads/2020-03-23_20-24-06_393_600x400.jpg 2x, ./generated_images/static/images/uploads/2020-03-23_20-24-06_393_900x600.jpg 3x, ./generated_images/static/images/uploads/2020-03-23_20-24-06_393_1200x800.jpg 4x"
|
srcset="/generated_images/images/uploads/2020-03-23_20-24-06_393_300x200.jpg 1x, /generated_images/images/uploads/2020-03-23_20-24-06_393_450x300.jpg 1.5x, /generated_images/images/uploads/2020-03-23_20-24-06_393_600x400.jpg 2x, /generated_images/images/uploads/2020-03-23_20-24-06_393_900x600.jpg 3x, /generated_images/images/uploads/2020-03-23_20-24-06_393_1200x800.jpg 4x"
|
||||||
type="image/jpeg"
|
type="image/jpeg"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
src="./generated_images/static/images/uploads/2020-03-23_20-24-06_393_300x200.jpg"
|
src="/generated_images/images/uploads/2020-03-23_20-24-06_393_300x200.jpg"
|
||||||
width="300"
|
width="300"
|
||||||
height="200"
|
height="200"
|
||||||
alt="Testing image alt"
|
alt="Testing image alt"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
! tailwindcss v3.4.9 | MIT License | https://tailwindcss.com
|
! tailwindcss v3.4.10 | MIT License | https://tailwindcss.com
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
<article class="grid grid-cols-[1fr_2fr] grid-flow-col gap-4">
|
<article class="grid grid-cols-[1fr_2fr] grid-flow-col gap-4">
|
||||||
<aside class="row-span-3">
|
<aside class="row-span-3">
|
||||||
<!-- TODO <figure> -->
|
{% match post.metadata.thumbnail %}
|
||||||
<!-- TODO Thumbnail -->
|
{% when Some with (orig_path) %}
|
||||||
<!-- <svg aria-hidden="true" class="h-12 w-12 fill-blue-950"> -->
|
{{ crate::picture_generator::picture_markup_generator::generate_picture_markup(orig_path, 180, 240, "Article thumbnail").unwrap()|safe }}
|
||||||
<!-- <use xlink:href="/svg/icons-sprite.svg#mail" /> -->
|
{% when None %}
|
||||||
<!-- </svg> -->
|
<div> TODO default obrazok </div>
|
||||||
<figure>
|
{% endmatch %}
|
||||||
</aside>
|
</aside>
|
||||||
<header>
|
<header>
|
||||||
<h3 class="text-lg font-bold mb-1">{{post.metadata.title}}</h3>
|
<h3 class="text-lg font-bold mb-1">{{post.metadata.title}}</h3>
|
||||||
|
Loading…
Reference in New Issue
Block a user