Skip to content

Commit

Permalink
Merge pull request #5 from michaelr0/develop
Browse files Browse the repository at this point in the history
Version 0.1.0
  • Loading branch information
michaelr0 authored Dec 18, 2021
2 parents fe07165 + b0db160 commit ab5d775
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 19 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "imeq"
description = "imeq aims to quickly compare two images to see if they are the same image"
version = "0.0.2"
version = "0.1.0"
edition = "2021"
categories = ["multimedia::images"]
exclude = ["images/*"]
Expand Down
58 changes: 41 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
imeq-rs aims to quickly compare two images to see if they are the same image.

## Installation
## Standalone

### Installation
```
cargo install imeq
```

## Usage
### Usage
```
USAGE:
imeq <IMAGE_1> <IMAGE_2>
Expand All @@ -19,13 +21,7 @@ ARGS:
<IMAGE_2> Sets the second image to use
```

## Building
Compiles to: `target/release/imeq`
```
cargo build --release
```

## Benchmark
### Benchmark
The below benchmarks have been done on a 2020 M1 Mac Mini with 16gb of ram and 256gb ssd, `hyperfine -w 3` is used and that command is then ran 3 times (outside of -w 3) and the result of the third run has been noted.

`baseline.jpeg` and `baseline_by_another_name.jpeg` should be identical, apart from the name.
Expand All @@ -34,40 +30,68 @@ The below benchmarks have been done on a 2020 M1 Mac Mini with 16gb of ram and 2

`modified.jpeg` has been modified so that the very last (bottom right) pixel is red.



### hyperfine -w 3 'target/release/imeq images/baseline.jpeg images/baseline.jpeg'
#### hyperfine -w 3 'target/release/imeq images/baseline.jpeg images/baseline.jpeg'
```bash
Time (mean ± σ): 1.1 ms ± 0.3 ms [User: 0.6 ms, System: 0.3 ms]
Range (min … max): 0.8 ms … 2.6 ms 857 runs
```

### hyperfine -w 3 'target/release/imeq images/baseline.jpeg images/baseline_by_another_name.jpeg'
#### hyperfine -w 3 'target/release/imeq images/baseline.jpeg images/baseline_by_another_name.jpeg'
```bash
Time (mean ± σ): 5.5 ms ± 0.4 ms [User: 7.4 ms, System: 2.3 ms]
Range (min … max): 5.1 ms … 7.5 ms 308 runs
```

### hyperfine -w 3 'target/release/imeq images/baseline.jpeg images/flipped.jpeg'
#### hyperfine -w 3 'target/release/imeq images/baseline.jpeg images/flipped.jpeg'
```bash
Time (mean ± σ): 93.7 ms ± 3.4 ms [User: 443.6 ms, System: 54.2 ms]
Range (min … max): 90.4 ms … 102.8 ms 31 runs
```

### hyperfine -w 3 'target/release/imeq images/baseline.jpeg images/modified.jpeg'
#### hyperfine -w 3 'target/release/imeq images/baseline.jpeg images/modified.jpeg'
```bash
Time (mean ± σ): 113.1 ms ± 0.9 ms [User: 471.1 ms, System: 53.4 ms]
Range (min … max): 111.4 ms … 115.5 ms 26 runs
```
## As a library

## Credits
### Installation
Add the following line to your Cargo.toml file:
```
imeq = "0.1.0"
```

or if you have `cargo edit` installed.
```
cargo add imeq
```

### Usage
```rust
let image_1 = "images/baseline.jpeg".to_string();

let image_2 = "images/modfied.jpeg".to_string();

let images_match = imeq::Compare::new(image_1, image_2)
.enable_check_images_have_same_path()
.enable_check_image_hashes_match()
.enable_check_images_dimensions_match()
.enable_check_images_pixels_match()
.are_match();

if images_match {
println!("Images are a match");
} else {
println!("Images are not a match");
}
```

## Credits
- [Handmade Web & Design](https://github.com/handmadeweb)
- [Michael Rook](https://github.com/michaelr0)
- [All Contributors](https://github.com/michaelr0/imeq-rs/graphs/contributors)

[Goat Image](https://unsplash.com/photos/J9wZ6D2kYPw) by [Florian van Duyn](https://unsplash.com/@flovayn)

## License

The MIT License (MIT). Please see [License File](https://github.com/michaelr0/imeq-rs/blob/main/LICENSE.md) for more information.
54 changes: 54 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,60 @@
//! imeq-rs aims to quickly compare two images to see if they are the same image.
//! Compare images
//! # Example
//! ```no_run
//! let image_1 = "images/baseline.jpeg".to_string();
//!
//! let image_2 = "images/modfied.jpeg".to_string();
//!
//! let images_match = imeq::Compare::new(image_1, image_2)
//! .enable_check_images_have_same_path()
//! .enable_check_image_hashes_match()
//! .enable_check_images_dimensions_match()
//! .enable_check_images_pixels_match()
//! .are_match();
//!
//! if images_match {
//! println!("Images are a match");
//! } else {
//! println!("Images are not a match");
//! }
//! ```
use image::{DynamicImage, GenericImageView, Pixels};
use rayon::prelude::*;
use ring::digest::{self};
use std::{collections::HashMap, fs::File, io::Read};

/// Compare images
/// # Example
/// ```no_run
/// let image_1 = "images/baseline.jpeg".to_string();
///
/// let image_2 = "images/modfied.jpeg".to_string();
///
/// let images_match = imeq::Compare::new(image_1, image_2)
/// .enable_check_images_have_same_path()
/// .enable_check_image_hashes_match()
/// .enable_check_images_dimensions_match()
/// .enable_check_images_pixels_match()
/// .are_match();
///
/// if images_match {
/// println!("Images are a match");
/// } else {
/// println!("Images are not a match");
/// }
/// ```
pub struct Compare<'a> {
/// Images to compare
images: [String; 2],
/// Checks that have been enabled or disabled
checks: HashMap<&'a str, bool>,
}

/// Compare images
impl Compare<'_> {
/// Create a new Image comparson
pub fn new(image_1: String, image_2: String) -> Self {
let mut compare = Compare {
images: [image_1, image_2],
Expand All @@ -23,32 +69,39 @@ impl Compare<'_> {
compare
}

/// Enable or disable a check
pub fn enable_check(&mut self, check: &'static str) -> &mut Self {
self.checks.insert(check, true);

self
}

/// Enable check for images having the same path
pub fn enable_check_images_have_same_path(&mut self) -> &mut Self {
self.enable_check("images_have_same_path")
}

/// Enable check for image hashes matching
pub fn enable_check_image_hashes_match(&mut self) -> &mut Self {
self.enable_check("image_hashes_match")
}

/// Enable check for image dimensions matching
pub fn enable_check_images_dimensions_match(&mut self) -> &mut Self {
self.enable_check("image_dimensions_match")
}

/// Enable check for image pixels matching
pub fn enable_check_images_pixels_match(&mut self) -> &mut Self {
self.enable_check("image_pixels_match")
}

/// Check to see if check is enabled
fn is_check_enabled(&self, check: &'static str) -> bool {
*self.checks.get(check).unwrap_or(&false)
}

/// Compare images and return if they are a match
pub fn are_match(&self) -> bool {
if self.is_check_enabled("images_have_same_path")
&& self.images.first() == self.images.last()
Expand Down Expand Up @@ -113,6 +166,7 @@ impl Compare<'_> {
false
}

/// Compare images and return if they are not a match
pub fn arent_match(&self) -> bool {
!self.are_match()
}
Expand Down
2 changes: 1 addition & 1 deletion src/main.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: imgeq
version: "0.0.2"
version: "0.1.0"
author: https://github.com/michaelr0/imeq-rs
settings:
- ArgRequiredElseHelp
Expand Down

0 comments on commit ab5d775

Please sign in to comment.