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
|
||||
*/
|
||||
|
||||
pub mod export_format;
|
||||
pub mod picture_markup_generator;
|
||||
|
@ -1,41 +1,16 @@
|
||||
use std::{
|
||||
cmp::Ordering,
|
||||
path::{Path, PathBuf},
|
||||
str::FromStr,
|
||||
str::FromStr as _,
|
||||
};
|
||||
|
||||
use axum::handler::HandlerWithoutStateExt;
|
||||
use anyhow::Context;
|
||||
use image::{GenericImageView, ImageReader};
|
||||
|
||||
use super::export_format::ExportFormat;
|
||||
|
||||
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(
|
||||
orig_img_path: &str,
|
||||
width: u32,
|
||||
@ -44,7 +19,13 @@ pub fn generate_picture_markup(
|
||||
) -> Result<String, anyhow::Error> {
|
||||
let exported_formats = get_export_formats(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 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
|
||||
.file_stem()
|
||||
.expect("There should be a name for every img");
|
||||
let result = Path::new("./generated_images/")
|
||||
.join(parent)
|
||||
let result = Path::new("/generated_images/")
|
||||
.join(parent.strip_prefix("/").unwrap())
|
||||
.join(file_name);
|
||||
result
|
||||
}
|
||||
|
||||
#[test]
|
||||
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!(
|
||||
get_generated_file_name(orig_img_path)
|
||||
.to_str()
|
||||
.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]
|
||||
fn test_get_export_formats() {
|
||||
assert_eq!(
|
||||
get_export_formats("./images/uploads/img_name.jpg"),
|
||||
get_export_formats("/images/uploads/img_name.jpg"),
|
||||
vec![ExportFormat::AVIF, ExportFormat::JPG]
|
||||
)
|
||||
}
|
||||
#[test]
|
||||
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 resolutions = vec![
|
||||
(320, 200, 1.),
|
||||
@ -286,7 +267,7 @@ fn test_generate_srcset() {
|
||||
(960, 600, 3.),
|
||||
(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!(
|
||||
generate_srcset(&orig_img_path, &export_format, &resolutions),
|
||||
result
|
||||
@ -297,18 +278,18 @@ fn test_generate_srcset() {
|
||||
fn test_generate_picture_markup() {
|
||||
let width = 300;
|
||||
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>
|
||||
<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"
|
||||
>
|
||||
<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"
|
||||
>
|
||||
<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"
|
||||
height="200"
|
||||
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">
|
||||
<aside class="row-span-3">
|
||||
<!-- TODO <figure> -->
|
||||
<!-- TODO Thumbnail -->
|
||||
<!-- <svg aria-hidden="true" class="h-12 w-12 fill-blue-950"> -->
|
||||
<!-- <use xlink:href="/svg/icons-sprite.svg#mail" /> -->
|
||||
<!-- </svg> -->
|
||||
<figure>
|
||||
{% match post.metadata.thumbnail %}
|
||||
{% when Some with (orig_path) %}
|
||||
{{ crate::picture_generator::picture_markup_generator::generate_picture_markup(orig_path, 180, 240, "Article thumbnail").unwrap()|safe }}
|
||||
{% when None %}
|
||||
<div> TODO default obrazok </div>
|
||||
{% endmatch %}
|
||||
</aside>
|
||||
<header>
|
||||
<h3 class="text-lg font-bold mb-1">{{post.metadata.title}}</h3>
|
||||
|
Loading…
Reference in New Issue
Block a user