Browse Source

imageproc: Fix naming, cleanup

index-subcmd
Vojtech Kral Vincent Prouillet 6 years ago
parent
commit
77bc526008
8 changed files with 99 additions and 87 deletions
  1. +28
    -33
      Cargo.lock
  2. +2
    -2
      components/content/src/page.rs
  3. +1
    -1
      components/errors/Cargo.toml
  4. +1
    -1
      components/imageproc/Cargo.toml
  5. +53
    -36
      components/imageproc/src/lib.rs
  6. +11
    -11
      docs/content/documentation/content/image-resizing/index.md
  7. +2
    -2
      docs/content/documentation/templates/pages-sections.md
  8. +1
    -1
      docs/templates/shortcodes/gallery.html

+ 28
- 33
Cargo.lock View File

@@ -310,14 +310,6 @@ dependencies = [
"strum_macros 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
name = "enum_primitive"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
name = "error-chain"
version = "0.11.0"
@@ -331,7 +323,7 @@ name = "errors"
version = "0.1.0"
dependencies = [
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"image 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
"image 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tera 0.11.8 (registry+https://github.com/rust-lang/crates.io-index)",
"toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -432,7 +424,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"

[[package]]
name = "gif"
version = "0.9.2"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"color_quant 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -540,17 +532,18 @@ dependencies = [

[[package]]
name = "image"
version = "0.18.0"
version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"enum_primitive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gif 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
"gif 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"jpeg-decoder 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
"lzw 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"num-derive 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"num-iter 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
"num-rational 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
"png 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
"png 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
"scoped_threadpool 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
]

@@ -559,7 +552,7 @@ name = "imageproc"
version = "0.1.0"
dependencies = [
"errors 0.1.0",
"image 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
"image 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -570,7 +563,7 @@ dependencies = [

[[package]]
name = "inflate"
version = "0.3.4"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -892,6 +885,17 @@ dependencies = [
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
name = "num-derive"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.14.2 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
name = "num-integer"
version = "0.1.39"
@@ -918,14 +922,6 @@ dependencies = [
"num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
name = "num-traits"
version = "0.1.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
name = "num-traits"
version = "0.2.5"
@@ -1066,12 +1062,12 @@ dependencies = [

[[package]]
name = "png"
version = "0.11.0"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"deflate 0.7.18 (registry+https://github.com/rust-lang/crates.io-index)",
"inflate 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"inflate 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"num-iter 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
]

@@ -1945,7 +1941,6 @@ dependencies = [
"checksum duct 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "166298c17c5b4fe5997b962c2f22e887c7c5adc44308eb9103ce5b66af45a423"
"checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0"
"checksum elasticlunr-rs 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4837d77a1e157489a3933b743fd774ae75074e0e390b2b7f071530048a0d87ee"
"checksum enum_primitive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "be4551092f4d519593039259a9ed8daedf0da12e5109c5280338073eaeb81180"
"checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3"
"checksum filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "714653f3e34871534de23771ac7b26e999651a0a228f47beb324dfdf1dd4b10f"
"checksum flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9fac2277e84e5e858483756647a9d0aa8d9a2b7cba517fd84325a0aaa69a0909"
@@ -1958,7 +1953,7 @@ dependencies = [
"checksum futf 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7c9c1ce3fa9336301af935ab852c437817d14cd33690446569392e65170aac3b"
"checksum gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)" = "5e33ec290da0d127825013597dbdfc28bee4964690c7ce1166cbc2a7bd08b1bb"
"checksum getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)" = "b900c08c1939860ce8b54dc6a89e26e00c04c380fd0e09796799bd7f12861e05"
"checksum gif 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2e41945ba23db3bf51b24756d73d81acb4f28d85c3dccc32c6fae904438c25f"
"checksum gif 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff3414b424657317e708489d2857d9575f4403698428b040b609b9d1c1a84a2c"
"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
"checksum globset 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "142754da2c9b3722affd909f9e27f2a6700a7a303f362971e0a74c652005a43d"
"checksum html5ever 0.22.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b04478cf718862650a0bf66acaf8f2f8c906fbc703f35c916c1f4211b069a364"
@@ -1966,8 +1961,8 @@ dependencies = [
"checksum humansize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b6cab2627acfc432780848602f3f558f7e9dd427352224b0d9324025796d2a5e"
"checksum hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)" = "368cb56b2740ebf4230520e2b90ebb0461e69034d85d1945febd9b3971426db2"
"checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d"
"checksum image 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)" = "545f000e8aa4e569e93f49c446987133452e0091c2494ac3efd3606aa3d309f2"
"checksum inflate 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f5f9f47468e9a76a6452271efadc88fe865a82be91fe75e6c0c57b87ccea59d4"
"checksum image 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ebdff791af04e30089bde8ad2a632b86af433b40c04db8d70ad4b21487db7a6a"
"checksum inflate 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4ec18d981200fd14e65ee8e35fb60ed1ce55227a02407303f3a72517c6146dcc"
"checksum inotify 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887fcc180136e77a85e6a6128579a719027b1bab9b1c38ea4444244fe262c20c"
"checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08"
"checksum iron 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d8e17268922834707e1c29e8badbf9c712c9c43378e1b6a3388946baff10be2"
@@ -2004,10 +1999,10 @@ dependencies = [
"checksum nix 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bfb3ddedaa14746434a02041940495bf11325c22f6d36125d3bdd56090d50a79"
"checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2"
"checksum notify 4.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5c3812da3098f210a0bb440f9c008471a031aa4c1de07a264fdd75456c95a4eb"
"checksum num-derive 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0d2c31b75c36a993d30c7a13d70513cb93f02acafdd5b7ba250f9b0e18615de7"
"checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea"
"checksum num-iter 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "af3fdbbc3291a5464dc57b03860ec37ca6bf915ed6ee385e7c6c052c422b2124"
"checksum num-rational 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "ee314c74bd753fc86b4780aa9475da469155f3848473a261d2d18e35245a784e"
"checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31"
"checksum num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "630de1ef5cc79d0cdd78b7e33b81f083cbfe90de0f4b2b2f07f905867c70e9fe"
"checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30"
"checksum onig 3.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f5eeb268a4620c74ea5768c6d2ccd492d60a47a8754666b91a46bfc35cd4d1ba"
@@ -2023,7 +2018,7 @@ dependencies = [
"checksum pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "110d5ee3593dbb73f56294327fe5668bcc997897097cbc76b51e7aed3f52452f"
"checksum plist 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c61ac2afed2856590ae79d6f358a24b85ece246d2aa134741a66d589519b7503"
"checksum plugin 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1a6a0dc3910bc8db877ffed8e457763b317cf880df4ae19109b9f77d277cf6e0"
"checksum png 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f0b0cabbbd20c2d7f06dbf015e06aad59b6ca3d9ed14848783e98af9aaf19925"
"checksum png 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f54b9600d584d3b8a739e1662a595fab051329eff43f20e7d8cc22872962145b"
"checksum precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
"checksum proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1b06e2f335f48d24442b35a19df506a835fb3547bc3c06ef27340da9acf5cae7"
"checksum proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "effdb53b25cdad54f8f48843d67398f7ef2e14f12c1b4cb4effc549a6462a4d6"


+ 2
- 2
components/content/src/page.rs View File

@@ -267,9 +267,9 @@ impl ser::Serialize for Page {
state.serialize_field("next", &self.next)?;
state.serialize_field("toc", &self.toc)?;
state.serialize_field("draft", &self.is_draft())?;
let (assets, assets_imgs) = self.serialize_assets();
let (assets, images) = self.serialize_assets();
state.serialize_field("assets", &assets)?;
state.serialize_field("assets_imgs", &assets_imgs)?;
state.serialize_field("images", &images)?;
state.end()
}
}


+ 1
- 1
components/errors/Cargo.toml View File

@@ -7,4 +7,4 @@ authors = ["Vincent Prouillet <prouillet.vincent@gmail.com>"]
error-chain = "0.11"
tera = "0.11"
toml = "0.4"
image = "0.18.0"
image = "0.19.0"

+ 1
- 1
components/imageproc/Cargo.toml View File

@@ -7,7 +7,7 @@ authors = ["Vojtěch Král <vojtech@kral.hk>"]
lazy_static = "1"
regex = "0.2"
tera = "0.11.0"
image = "0.18.0"
image = "0.19.0"
rayon = "0.9"
twox-hash = "1.1"



+ 53
- 36
components/imageproc/src/lib.rs View File

@@ -52,8 +52,8 @@ impl ResizeOp {

// Validate args:
match op {
"fitwidth" => if width.is_none() { return Err(format!("op=fitwidth requires a `width` argument").into()) },
"fitheight" => if height.is_none() { return Err(format!("op=fitwidth requires a `height` argument").into()) },
"fit_width" => if width.is_none() { return Err(format!("op=\"fit_width\" requires a `width` argument").into()) },
"fit_height" => if height.is_none() { return Err(format!("op=\"fit_height\" requires a `height` argument").into()) },
"scale" | "fit" | "fill" => if width.is_none() || height.is_none() {
return Err(format!("op={} requires a `width` and `height` argument", op).into())
},
@@ -62,8 +62,8 @@ impl ResizeOp {

Ok(match op {
"scale" => Scale(width.unwrap(), height.unwrap()),
"fitwidth" => FitWidth(width.unwrap()),
"fitheight" => FitHeight(height.unwrap()),
"fit_width" => FitWidth(width.unwrap()),
"fit_height" => FitHeight(height.unwrap()),
"fit" => Fit(width.unwrap(), height.unwrap()),
"fill" => Fill(width.unwrap(), height.unwrap()),
_ => unreachable!(),
@@ -123,6 +123,7 @@ pub struct ImageOp {
source: String,
op: ResizeOp,
quality: u8,
/// Hash of the above parameters
hash: u64,
collision: Option<u32>,
}
@@ -143,7 +144,7 @@ impl ImageOp {
Ok(Self::new(source, op, quality))
}

fn num_colli(&self) -> u32 { self.collision.unwrap_or(0) }
fn num_collisions(&self) -> u32 { self.collision.unwrap_or(0) }

fn perform(&self, content_path: &Path, target_path: &Path) -> Result<()> {
use ResizeOp::*;
@@ -165,24 +166,30 @@ impl ImageOp {
FitHeight(h) => img.resize(u32::max_value(), h, RESIZE_FILTER),
Fit(w, h) => img.resize(w, h, RESIZE_FILTER),
Fill(w, h) => {
let fw = img_w as f32 / w as f32;
let fh = img_h as f32 / h as f32;
let factor_w = img_w as f32 / w as f32;
let factor_h = img_h as f32 / h as f32;

if (fw - fh).abs() <= RATIO_EPSILLION {
// The aspect is similar enough that there's not much point in cropping
if (factor_w - factor_h).abs() <= RATIO_EPSILLION {
// If the horizontal and vertical factor is very similar, that means the aspect is similar enough
// that there's not much point in cropping, so just perform a simple scale in this case.
img.resize_exact(w, h, RESIZE_FILTER)
} else {
// We perform the fill such that a crop is performed first and then resize_exact can be used,
// which should be cheaper than resizing and then cropping (smaller number of pixels to resize).
let (crop_w, crop_h) = match fw < fh {
true => (img_w, (fw * h as f32).round() as u32),
false => ((fh * w as f32).round() as u32, img_h),

let (crop_w, crop_h) = if factor_w < factor_h {
(img_w, (factor_w * h as f32).round() as u32)
} else {
((factor_h * w as f32).round() as u32, img_h)
};
let (off_w, off_h) = match fw < fh {
true => (0, (img_h - crop_h) / 2),
false => ((img_w - crop_w) / 2, 0),

let (offset_w, offset_h) = if factor_w < factor_h {
(0, (img_h - crop_h) / 2)
} else {
((img_w - crop_w) / 2, 0)
};
img.crop(off_w, off_h, crop_w, crop_h).resize_exact(w, h, RESIZE_FILTER)

img.crop(offset_w, offset_h, crop_w, crop_h).resize_exact(w, h, RESIZE_FILTER)
}
},
};
@@ -204,9 +211,12 @@ pub struct Processor {
content_path: PathBuf,
resized_path: PathBuf,
resized_url: String,
/// A map of a ImageOps by their stored hash.
/// Note that this cannot be a HashSet, because hashest handles collisions and we don't want that,
/// we need to be aware of and handle collisions ourselves.
img_ops: HashMap<u64, ImageOp>,
// Hash collisions go here:
img_ops_colls: Vec<ImageOp>,
/// Hash collisions go here:
img_ops_collisions: Vec<ImageOp>,
}

impl Processor {
@@ -216,14 +226,15 @@ impl Processor {
resized_path: static_path.join(RESIZED_SUBDIR),
resized_url: Self::resized_url(base_url),
img_ops: HashMap::new(),
img_ops_colls: Vec::new(),
img_ops_collisions: Vec::new(),
}
}

fn resized_url(base_url: &str) -> String {
match base_url.ends_with('/') {
true => format!("{}{}", base_url, RESIZED_SUBDIR),
false => format!("{}/{}", base_url, RESIZED_SUBDIR),
if base_url.ends_with('/') {
format!("{}{}", base_url, RESIZED_SUBDIR)
} else {
format!("{}/{}", base_url, RESIZED_SUBDIR)
}
}

@@ -236,10 +247,10 @@ impl Processor {
}

pub fn num_img_ops(&self) -> usize {
self.img_ops.len() + self.img_ops_colls.len()
self.img_ops.len() + self.img_ops_collisions.len()
}

fn insert_with_colls(&mut self, mut img_op: ImageOp) -> u32 {
fn insert_with_collisions(&mut self, mut img_op: ImageOp) -> u32 {
match self.img_ops.entry(img_op.hash) {
HEntry::Occupied(entry) => if *entry.get() == img_op { return 0; },
HEntry::Vacant(entry) => {
@@ -249,37 +260,43 @@ impl Processor {
}

// If we get here, that means a hash collision.
// This is detected when there is an ImageOp with the same hash in the `img_ops` map but which is not equal to this one.
// To deal with this, all collisions get a (random) sequential ID number.

// First try to look up this ImageOp in `img_ops_collisions`, maybe we've already seen the same ImageOp
let mut num = 1;
for op in self.img_ops_colls.iter().filter(|op| op.hash == img_op.hash) {
for op in self.img_ops_collisions.iter().filter(|op| op.hash == img_op.hash) {
if *op == img_op {
// This is a colliding ImageOp, but we've already seen the very same one, so just return its ID
return num;
} else {
num += 1;
}
}

// If we get here, that means this is a new colliding ImageOp and `num` has the next free ID
if num == 1 {
self.img_ops.get_mut(&img_op.hash).unwrap().collision = Some(0);
}
img_op.collision = Some(num);
self.img_ops_colls.push(img_op);
self.img_ops_collisions.push(img_op);
num
}

fn op_filename(hash: u64, colli_num: u32) -> String {
fn op_filename(hash: u64, num_collisions: u32) -> String {
// Please keep this in sync with RESIZED_FILENAME
assert!(colli_num < 256, "Unexpectedly large number of collisions: {}", colli_num);
format!("{:016x}{:02x}.jpg", hash, colli_num)
assert!(num_collisions < 256, "Unexpectedly large number of collisions: {}", num_collisions);
format!("{:016x}{:02x}.jpg", hash, num_collisions)
}

fn op_url(&self, hash: u64, colli_num: u32) -> String {
format!("{}/{}", &self.resized_url, Self::op_filename(hash, colli_num))
fn op_url(&self, hash: u64, num_collisions: u32) -> String {
format!("{}/{}", &self.resized_url, Self::op_filename(hash, num_collisions))
}

pub fn insert(&mut self, img_op: ImageOp) -> String {
let hash = img_op.hash;
let num_colli = self.insert_with_colls(img_op);
self.op_url(hash, num_colli)
let num_collisions = self.insert_with_collisions(img_op);
self.op_url(hash, num_collisions)
}

pub fn prune(&self) -> Result<()> {
@@ -291,8 +308,8 @@ impl Processor {
let filename = entry_path.file_name().unwrap().to_string_lossy();
if let Some(capts) = RESIZED_FILENAME.captures(filename.as_ref()) {
let hash = u64::from_str_radix(capts.get(1).unwrap().as_str(), 16).unwrap();
let num_colli = u32::from_str_radix(capts.get(2).unwrap().as_str(), 16).unwrap();
if num_colli > 0 || !self.img_ops.contains_key(&hash) {
let num_collisions = u32::from_str_radix(capts.get(2).unwrap().as_str(), 16).unwrap();
if num_collisions > 0 || !self.img_ops.contains_key(&hash) {
fs::remove_file(&entry_path)?;
}
}
@@ -303,7 +320,7 @@ impl Processor {

pub fn do_process(&mut self) -> Result<()> {
self.img_ops.par_iter().map(|(hash, op)| {
let target = self.resized_path.join(Self::op_filename(*hash, op.num_colli()));
let target = self.resized_path.join(Self::op_filename(*hash, op.num_collisions()));
op.perform(&self.content_path, &target)
.chain_err(|| format!("Failed to process image: {}", op.source))
})


+ 11
- 11
docs/content/documentation/content/image-resizing/index.md View File

@@ -17,7 +17,7 @@ The function usage is as follows:
- `path`: The path to the source image relative to the `content` directory in the [directory structure](./documentation/getting-started/directory-structure.md).

- `width` and `height`: The dimensions in pixels of the resized image. Usage depends on the `op` argument.
- `op`: Resize operation. This can be one of five choices: `"scale"`, `"fitwidth"`, `"fitheight"`, `"fit"`, or `"fill"`.
- `op`: Resize operation. This can be one of five choices: `"scale"`, `"fit_width"`, `"fit_height"`, `"fit"`, or `"fill"`.
What each of these does is explained below.
This argument is optional, default value is `"fill"`.
- `quality`: JPEG quality of the resized image, in percents. Optional argument, default value is `75`.
@@ -48,24 +48,24 @@ The source for all examples is this 300 × 380 pixels image:

{{ resize_image(path="documentation/content/image-resizing/gutenberg.jpg", width=150, height=150, op="scale") }}

### **`"fitwidth"`**
### **`"fit_width"`**
Resizes the image such that the resulting width is `width` and height is whatever will preserve the aspect ratio.
The `height` argument is not needed.

`resize_image(..., width=100, op="fitwidth")`
`resize_image(..., width=100, op="fit_width")`

{{ resize_image(path="documentation/content/image-resizing/gutenberg.jpg", width=100, height=0, op="fitwidth") }}
{{ resize_image(path="documentation/content/image-resizing/gutenberg.jpg", width=100, height=0, op="fit_width") }}

### **`"fitheight"`**
### **`"fit_height"`**
Resizes the image such that the resulting height is `height` and width is whatever will preserve the aspect ratio.
The `width` argument is not needed.

`resize_image(..., height=150, op="fitheight")`
`resize_image(..., height=150, op="fit_height")`

{{ resize_image(path="documentation/content/image-resizing/gutenberg.jpg", width=0, height=150, op="fitheight") }}
{{ resize_image(path="documentation/content/image-resizing/gutenberg.jpg", width=0, height=150, op="fit_height") }}

### **`"fit"`**
Like `"fitwidth"` and `"fitheight"` combined.
Like `"fit_width"` and `"fit_height"` combined.
Resizes the image such that the result fits within `width` and `height` preserving aspect ratio. This means that both width or height
will be at max `width` and `height`, respectively, but possibly one of them smaller so as to preserve the aspect ratio.

@@ -97,15 +97,15 @@ The examples above were generated using a shortcode file named `resize_image.htm

The `resize_image()` can be used multiple times and/or in loops (it is designed to handle this efficiently).

This can be used along with `assets_imgs` [page metadata](./documentation/templates/pages-sections.md) to create picture galleries.
The `assets_imgs` variable holds paths to all images in the directory of a page with resources
This can be used along with `images` [page metadata](./documentation/templates/pages-sections.md) to create picture galleries.
The `images` variable holds paths to all images in the directory of a page with resources
(see [Assets colocation](./documentation/content/overview.md#assets-colocation)).

This can be used in shortcodes. For example, we can create a very simple html-only clickable
picture gallery with the following shortcode named `gallery.html`:

```jinja2
{% for img in page.assets_imgs %}
{% for img in page.images %}
<a href="{{ config.base_url }}/{{ img }}">
<img src="{{ resize_image(path=img, width=240, height=180) }}" />
</a>


+ 2
- 2
docs/content/documentation/templates/pages-sections.md View File

@@ -40,11 +40,11 @@ toc: Array<Header>;
// Paths of colocated assets, relative to the content directory
assets: Array<String>;
// Paths of colocated image assets, ie. files with an extension of "jpg", "jpeg", "png", "gif", or "bmp"
assets_imgs: Array<String>;
images: Array<String>;
```

## Section variables
By default, Gutenberg will try to load `templates/index.html` for `content/_index.md`
By default, Gutenberg will try to load `templates/index.html` for `content/_index.md`
and `templates/section.html` for others `_index.md` files. If there isn't
one, it will render the built-in template: a blank page.



+ 1
- 1
docs/templates/shortcodes/gallery.html View File

@@ -1,4 +1,4 @@
{% for img in page.assets_imgs %}
{% for img in page.images %}
<a href="{{ config.base_url }}/{{ img }}">
<img src="{{ resize_image(path=img, width=240, height=180, op="fill") }}" />
</a>


Loading…
Cancel
Save