mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2024-11-11 01:55:38 +08:00
Merge pull request #2239 from socram8888/waveshare-gd
Add image cropping and scaling
This commit is contained in:
commit
e2a3aea75b
4 changed files with 77 additions and 16 deletions
|
@ -9,6 +9,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
|
|||
- Fixed `lf pyramid sim` - wrong parameter handling (@iceman1001)
|
||||
- Fixed bootloader - Ignore jitters when pressing the button (@wh201906)
|
||||
- Changed `hf waveshare` - image loading and processing is now done using [GDlib](https://github.com/libgd/libgd) (@socram8888)
|
||||
- Changed `hf waveshare` - image is automatically scaled and cropped to match panel size (@socram8888)
|
||||
|
||||
## [Steamboat Willie.4.17768][2024-01-03]
|
||||
- Changed `mem spiffs dump -t` - now supports downloading direct into trace buffer (@hazardousvoltage)
|
||||
|
|
|
@ -631,14 +631,13 @@ static int CmdHF14AWSLoad(const char *Cmd) {
|
|||
return PM3_EFILE;
|
||||
}
|
||||
|
||||
if (
|
||||
gdImageSX(rgb_img) != models[model_nr].width ||
|
||||
gdImageSY(rgb_img) != models[model_nr].height
|
||||
) {
|
||||
PrintAndLogEx(WARNING, "Image size does not match panel size");
|
||||
gdImagePtr scaled_img = img_crop_to_fit(rgb_img, models[model_nr].width, models[model_nr].height);
|
||||
if (scaled_img == NULL) {
|
||||
PrintAndLogEx(WARNING, "Failed to scale input image");
|
||||
gdImageDestroy(rgb_img);
|
||||
return PM3_EFILE;
|
||||
}
|
||||
gdImageDestroy(rgb_img);
|
||||
|
||||
int pal_len = 2;
|
||||
int pal[3];
|
||||
|
@ -649,8 +648,8 @@ static int CmdHF14AWSLoad(const char *Cmd) {
|
|||
pal[2] = gdTrueColorAlpha(0xFF, 0x00, 0x00, 0); // Red
|
||||
}
|
||||
|
||||
gdImagePtr pal_img = img_palettize(rgb_img, pal, pal_len);
|
||||
gdImageDestroy(rgb_img);
|
||||
gdImagePtr pal_img = img_palettize(scaled_img, pal, pal_len);
|
||||
gdImageDestroy(scaled_img);
|
||||
|
||||
if (!pal_img) {
|
||||
PrintAndLogEx(WARNING, "Could not convert image");
|
||||
|
@ -662,7 +661,7 @@ static int CmdHF14AWSLoad(const char *Cmd) {
|
|||
PrintAndLogEx(INFO, "Save converted image to " _YELLOW_("%s"), outfile);
|
||||
gdImageDestroy(pal_img);
|
||||
return PM3_SUCCESS;
|
||||
} else {
|
||||
} else {
|
||||
PrintAndLogEx(WARNING, "Could not save converted image", outfile);
|
||||
gdImageDestroy(pal_img);
|
||||
return PM3_EFILE;
|
||||
|
|
|
@ -33,14 +33,6 @@ static inline void cap_comp(int * x) {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The following function implements a Floyd-Steinberg in YCbCr color space.
|
||||
*
|
||||
* Using this colorspace, the Euclidean distance between colors is closer to human perception than
|
||||
* in sRGB, which results in a more accurate color rendering.
|
||||
*
|
||||
* A comparison can be found at https://twitter.com/Socram4x8/status/1733157380097995205/photo/1.
|
||||
*/
|
||||
gdImagePtr img_palettize(gdImagePtr rgb, int * palette, int palette_size) {
|
||||
assert(rgb != NULL);
|
||||
assert(palette != NULL);
|
||||
|
@ -157,3 +149,58 @@ gdImagePtr img_palettize(gdImagePtr rgb, int * palette, int palette_size) {
|
|||
free(pal_ycbcr);
|
||||
return res;
|
||||
}
|
||||
|
||||
gdImagePtr img_crop_to_fit(gdImagePtr orig, int width, int height) {
|
||||
assert(orig != NULL);
|
||||
assert(width >= 1);
|
||||
assert(height >= 1);
|
||||
|
||||
gdImagePtr res;
|
||||
if (gdImageTrueColor(orig)) {
|
||||
res = gdImageCreateTrueColor(width, height);
|
||||
} else {
|
||||
res = gdImageCreate(width, height);
|
||||
}
|
||||
|
||||
if (!res) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (gdImageSY(orig) * width <= gdImageSX(orig) * height) {
|
||||
// Image is wider than expected, so we will crop the left and right sides
|
||||
|
||||
int crop_width = gdImageSY(orig) * width / height;
|
||||
int crop_sx = gdImageSX(orig) / 2 - crop_width / 2;
|
||||
gdImageCopyResampled(
|
||||
res, // Dest img
|
||||
orig, // Src image
|
||||
0, // Dest X
|
||||
0, // Dest Y
|
||||
crop_sx, // Src X
|
||||
0, // Src Y
|
||||
width, // Dest width
|
||||
height, // Dest height
|
||||
crop_width, // Src width
|
||||
gdImageSY(orig) // Src height
|
||||
);
|
||||
} else {
|
||||
// Image is taller than expected, so we will crop the top and bottom sides
|
||||
|
||||
int crop_height = gdImageSX(orig) * height / width;
|
||||
int crop_sy = gdImageSY(orig) / 2 - crop_height / 2;
|
||||
gdImageCopyResampled(
|
||||
res, // Dest img
|
||||
orig, // Src image
|
||||
0, // Dest X
|
||||
0, // Dest Y
|
||||
0, // Src X
|
||||
crop_sy, // Src Y
|
||||
width, // Dest width
|
||||
height, // Dest height
|
||||
gdImageSX(orig), // Src width
|
||||
crop_height // Src height
|
||||
);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -20,6 +20,20 @@
|
|||
|
||||
#include <gd.h>
|
||||
|
||||
/*
|
||||
* Converts a true color image to a palette image, using Floyd-Steinberg dithering.
|
||||
*
|
||||
* For color matching, this function uses the Euclidean distance between colors in the
|
||||
* YCbCr color space, which yields to better results than using sRGB directly.
|
||||
*
|
||||
* A comparison can be found at https://twitter.com/Socram4x8/status/1733157380097995205/photo/1.
|
||||
*/
|
||||
gdImagePtr img_palettize(gdImagePtr rgb, int * palette, int palette_size);
|
||||
|
||||
/*
|
||||
* This function scales and crops the image to the given size.
|
||||
* Think of "background-size: cover" in CSS.
|
||||
*/
|
||||
gdImagePtr img_crop_to_fit(gdImagePtr orig, int width, int height);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue