mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-29 01:25:38 +00:00
Added options to the miximage generator for how to fit screenshots that do not match the aspect ratio of the miximage frame
This commit is contained in:
parent
bf106711cb
commit
923240aac0
|
@ -409,16 +409,100 @@ bool MiximageGenerator::generateImage()
|
||||||
if (Settings::getInstance()->getBool("MiximageRemovePillarboxes"))
|
if (Settings::getInstance()->getBool("MiximageRemovePillarboxes"))
|
||||||
Utils::CImg::cropPillarboxes(screenshotImage);
|
Utils::CImg::cropPillarboxes(screenshotImage);
|
||||||
|
|
||||||
if (Settings::getInstance()->getString("MiximageScreenshotScaling") == "smooth") {
|
const float fileAspect {static_cast<float>(fileWidth) / static_cast<float>(fileHeight)};
|
||||||
// Lanczos scaling is normally not recommended for low resolution graphics as
|
|
||||||
// it makes the pixels appear smooth when scaling, but for more modern game
|
// Options for how to handle screenshots that are not closely matching the aspect ratio of
|
||||||
// platforms it may be a good idea to use it.
|
// the miximage. Can be set to contain, crop or stretch.
|
||||||
screenshotImage.resize(screenshotWidth, screenshotHeight, 1, 4, 6);
|
const bool containImage {
|
||||||
|
(fileAspect >= 1.0f &&
|
||||||
|
Settings::getInstance()->getString("MiximageScreenshotHorizontalFit") == "contain") ||
|
||||||
|
(fileAspect < 1.0f &&
|
||||||
|
Settings::getInstance()->getString("MiximageScreenshotVerticalFit") == "contain")};
|
||||||
|
const bool cropImage {
|
||||||
|
(fileAspect >= 1.0f &&
|
||||||
|
Settings::getInstance()->getString("MiximageScreenshotHorizontalFit") == "crop") ||
|
||||||
|
(fileAspect < 1.0f &&
|
||||||
|
Settings::getInstance()->getString("MiximageScreenshotVerticalFit") == "crop")};
|
||||||
|
|
||||||
|
// Define a threshold higher and lower than the 1.325 aspect ratio of the miximage to avoid
|
||||||
|
// fitting and cropping images which only deviate slightly.
|
||||||
|
const float miximageAspectRatio {1.325f};
|
||||||
|
const float maxAspectValue {
|
||||||
|
Settings::getInstance()->getString("MiximageScreenshotAspectThreshold") == "high" ? 1.6f :
|
||||||
|
1.375f};
|
||||||
|
const float minAspectValue {
|
||||||
|
Settings::getInstance()->getString("MiximageScreenshotAspectThreshold") == "high" ? 1.05f :
|
||||||
|
1.275f};
|
||||||
|
|
||||||
|
// Set the frame color based on an average of the screenshot contents.
|
||||||
|
unsigned char frameColor[] = {0, 0, 0, 0};
|
||||||
|
|
||||||
|
// Lanczos scaling (6) is normally not recommended for low resolution graphics as it makes the
|
||||||
|
// the pixels appear smooth when scaling, but for more modern game platforms it may be a good
|
||||||
|
// idea to use it. Box interpolation (1) gives completely sharp pixels, which is best suited
|
||||||
|
// for low resolution retro games.
|
||||||
|
const int scalingMethod {
|
||||||
|
Settings::getInstance()->getString("MiximageScreenshotScaling") == "smooth" ? 6 : 1};
|
||||||
|
|
||||||
|
if (cropImage && (fileAspect > maxAspectValue || fileAspect < minAspectValue)) {
|
||||||
|
if (fileWidth >= fileHeight && fileAspect > miximageAspectRatio) {
|
||||||
|
screenshotImage.resize(
|
||||||
|
static_cast<int>(std::round(static_cast<float>(screenshotHeight) * fileAspect)),
|
||||||
|
screenshotHeight, 1, 4, scalingMethod);
|
||||||
|
const int offsetX {(screenshotImage.width() - static_cast<int>(screenshotWidth)) / 2};
|
||||||
|
// Add -2 to the offset to avoid single-pixel black lines caused by inexact rounding.
|
||||||
|
screenshotImage.crop(offsetX, 0, 0, 3, screenshotWidth + offsetX, screenshotHeight - 2,
|
||||||
|
0, 0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
screenshotImage.resize(
|
||||||
|
screenshotWidth,
|
||||||
|
static_cast<int>(std::round(static_cast<float>(screenshotWidth) / fileAspect)), 1,
|
||||||
|
4, scalingMethod);
|
||||||
|
const int offsetY {(screenshotImage.height() - static_cast<int>(screenshotHeight)) / 2};
|
||||||
|
screenshotImage.crop(0, offsetY, 0, 3, screenshotWidth - 2, screenshotHeight + offsetY,
|
||||||
|
0, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Box interpolation gives completely sharp pixels, which is best suited for
|
screenshotImage.resize(screenshotWidth, screenshotHeight, 1, 4, scalingMethod);
|
||||||
// low resolution retro games.
|
}
|
||||||
screenshotImage.resize(screenshotWidth, screenshotHeight, 1, 4, 1);
|
|
||||||
|
if (containImage && (fileAspect > maxAspectValue || fileAspect < minAspectValue)) {
|
||||||
|
CImg<unsigned char> tempImage(fileWidth, fileHeight, 1, 4, 0);
|
||||||
|
sampleFrameColor(screenshotImage, frameColor);
|
||||||
|
tempImage = screenshotImage;
|
||||||
|
if (Settings::getInstance()->getString("MiximageScreenshotBlankAreasColor") == "frame") {
|
||||||
|
screenshotImage.get_shared_channel(0).fill(frameColor[0]);
|
||||||
|
screenshotImage.get_shared_channel(1).fill(frameColor[1]);
|
||||||
|
screenshotImage.get_shared_channel(2).fill(frameColor[2]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
screenshotImage.fill(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fileWidth >= fileHeight && fileAspect > miximageAspectRatio) {
|
||||||
|
const float sizeRatio {static_cast<float>(screenshotWidth) /
|
||||||
|
static_cast<float>(fileWidth)};
|
||||||
|
const int resizeHeight {static_cast<int>(static_cast<float>(fileHeight) * sizeRatio)};
|
||||||
|
tempImage.resize(
|
||||||
|
screenshotWidth,
|
||||||
|
static_cast<int>(std::round(static_cast<float>(fileHeight) * sizeRatio)), 1, 4,
|
||||||
|
scalingMethod);
|
||||||
|
screenshotImage.draw_image(0, (screenshotHeight - resizeHeight) / 2, tempImage);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const float sizeRatio {static_cast<float>(screenshotHeight) /
|
||||||
|
static_cast<float>(fileHeight)};
|
||||||
|
const int resizeWidth {static_cast<int>(static_cast<float>(fileWidth) * sizeRatio)};
|
||||||
|
tempImage.resize(
|
||||||
|
static_cast<int>(std::round(static_cast<float>(fileWidth) * sizeRatio)),
|
||||||
|
screenshotHeight, 1, 4, scalingMethod);
|
||||||
|
screenshotImage.draw_image((screenshotWidth - resizeWidth) / 2, 0, tempImage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sampleFrameColor(screenshotImage, frameColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove any transparency information from the screenshot. There really should be no
|
// Remove any transparency information from the screenshot. There really should be no
|
||||||
|
@ -454,8 +538,8 @@ bool MiximageGenerator::generateImage()
|
||||||
|
|
||||||
CImg<unsigned char> frameImage(mWidth, mHeight, 1, 4, 0);
|
CImg<unsigned char> frameImage(mWidth, mHeight, 1, 4, 0);
|
||||||
|
|
||||||
xPosScreenshot = canvasImage.width() / 2 - screenshotImage.width() / 2 + screenshotOffset;
|
xPosScreenshot = canvasImage.width() / 2 - screenshotWidth / 2 + screenshotOffset;
|
||||||
yPosScreenshot = canvasImage.height() / 2 - screenshotImage.height() / 2;
|
yPosScreenshot = canvasImage.height() / 2 - screenshotHeight / 2;
|
||||||
|
|
||||||
if (mMarquee) {
|
if (mMarquee) {
|
||||||
if (FreeImage_GetBPP(marqueeFile) != 32) {
|
if (FreeImage_GetBPP(marqueeFile) != 32) {
|
||||||
|
@ -617,10 +701,6 @@ bool MiximageGenerator::generateImage()
|
||||||
frameImageAlpha.draw_image(xPosPhysicalMedia, yPosPhysicalMedia, physicalMediaImageAlpha);
|
frameImageAlpha.draw_image(xPosPhysicalMedia, yPosPhysicalMedia, physicalMediaImageAlpha);
|
||||||
frameImageAlpha.draw_image(xPosMarquee, yPosMarquee, marqueeImageAlpha);
|
frameImageAlpha.draw_image(xPosMarquee, yPosMarquee, marqueeImageAlpha);
|
||||||
|
|
||||||
// Set a frame color based on an average of the screenshot contents.
|
|
||||||
unsigned char frameColor[] = {0, 0, 0, 0};
|
|
||||||
sampleFrameColor(screenshotImage, frameColor);
|
|
||||||
|
|
||||||
// Upper / lower frame.
|
// Upper / lower frame.
|
||||||
frameImage.draw_rectangle(xPosScreenshot + 2, yPosScreenshot - screenshotFrameWidth,
|
frameImage.draw_rectangle(xPosScreenshot + 2, yPosScreenshot - screenshotFrameWidth,
|
||||||
xPosScreenshot + screenshotWidth - 2,
|
xPosScreenshot + screenshotWidth - 2,
|
||||||
|
|
|
@ -468,6 +468,92 @@ void GuiScraperMenu::openMiximageOptions()
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Horizontally oriented screenshots fit.
|
||||||
|
auto miximageHorizontalFit = std::make_shared<OptionListComponent<std::string>>(
|
||||||
|
getHelpStyle(), "HORIZONTAL SCREENSHOT FIT", false);
|
||||||
|
const std::string selectedHorizontalFit {
|
||||||
|
Settings::getInstance()->getString("MiximageScreenshotHorizontalFit")};
|
||||||
|
miximageHorizontalFit->add("contain", "contain", selectedHorizontalFit == "contain");
|
||||||
|
miximageHorizontalFit->add("crop", "crop", selectedHorizontalFit == "crop");
|
||||||
|
miximageHorizontalFit->add("stretch", "stretch", selectedHorizontalFit == "stretch");
|
||||||
|
// If there are no objects returned, then there must be a manually modified entry in the
|
||||||
|
// configuration file. Simply set the horizontal screenshot fit to "crop" in this case.
|
||||||
|
if (miximageHorizontalFit->getSelectedObjects().size() == 0)
|
||||||
|
miximageHorizontalFit->selectEntry(1);
|
||||||
|
s->addWithLabel("HORIZONTAL SCREENSHOT FIT", miximageHorizontalFit);
|
||||||
|
s->addSaveFunc([miximageHorizontalFit, s] {
|
||||||
|
if (miximageHorizontalFit->getSelected() !=
|
||||||
|
Settings::getInstance()->getString("MiximageScreenshotHorizontalFit")) {
|
||||||
|
Settings::getInstance()->setString("MiximageScreenshotHorizontalFit",
|
||||||
|
miximageHorizontalFit->getSelected());
|
||||||
|
s->setNeedsSaving();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Vertically oriented screenshots fit.
|
||||||
|
auto miximageVerticalFit = std::make_shared<OptionListComponent<std::string>>(
|
||||||
|
getHelpStyle(), "VERTICAL SCREENSHOT FIT", false);
|
||||||
|
const std::string selectedVerticalFit {
|
||||||
|
Settings::getInstance()->getString("MiximageScreenshotVerticalFit")};
|
||||||
|
miximageVerticalFit->add("contain", "contain", selectedVerticalFit == "contain");
|
||||||
|
miximageVerticalFit->add("crop", "crop", selectedVerticalFit == "crop");
|
||||||
|
miximageVerticalFit->add("stretch", "stretch", selectedVerticalFit == "stretch");
|
||||||
|
// If there are no objects returned, then there must be a manually modified entry in the
|
||||||
|
// configuration file. Simply set the vertical screenshot fit to "contain" in this case.
|
||||||
|
if (miximageVerticalFit->getSelectedObjects().size() == 0)
|
||||||
|
miximageVerticalFit->selectEntry(0);
|
||||||
|
s->addWithLabel("VERTICAL SCREENSHOT FIT", miximageVerticalFit);
|
||||||
|
s->addSaveFunc([miximageVerticalFit, s] {
|
||||||
|
if (miximageVerticalFit->getSelected() !=
|
||||||
|
Settings::getInstance()->getString("MiximageScreenshotVerticalFit")) {
|
||||||
|
Settings::getInstance()->setString("MiximageScreenshotVerticalFit",
|
||||||
|
miximageVerticalFit->getSelected());
|
||||||
|
s->setNeedsSaving();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Screenshots aspect ratio threshold.
|
||||||
|
auto miximageAspectThreshold = std::make_shared<OptionListComponent<std::string>>(
|
||||||
|
getHelpStyle(), "ASPECT RATIO THRESHOLD", false);
|
||||||
|
const std::string selectedAspectThreshold {
|
||||||
|
Settings::getInstance()->getString("MiximageScreenshotAspectThreshold")};
|
||||||
|
miximageAspectThreshold->add("high", "high", selectedAspectThreshold == "high");
|
||||||
|
miximageAspectThreshold->add("low", "low", selectedAspectThreshold == "low");
|
||||||
|
// If there are no objects returned, then there must be a manually modified entry in the
|
||||||
|
// configuration file. Simply set the screenshot aspect threshold to "high" in this case.
|
||||||
|
if (miximageAspectThreshold->getSelectedObjects().size() == 0)
|
||||||
|
miximageAspectThreshold->selectEntry(0);
|
||||||
|
s->addWithLabel("SCREENSHOT ASPECT RATIO THRESHOLD", miximageAspectThreshold);
|
||||||
|
s->addSaveFunc([miximageAspectThreshold, s] {
|
||||||
|
if (miximageAspectThreshold->getSelected() !=
|
||||||
|
Settings::getInstance()->getString("MiximageScreenshotAspectThreshold")) {
|
||||||
|
Settings::getInstance()->setString("MiximageScreenshotAspectThreshold",
|
||||||
|
miximageAspectThreshold->getSelected());
|
||||||
|
s->setNeedsSaving();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Blank areas fill color.
|
||||||
|
auto miximageBlankAreasColor = std::make_shared<OptionListComponent<std::string>>(
|
||||||
|
getHelpStyle(), "BLANK AREAS FILL COLOR", false);
|
||||||
|
const std::string selectedBlankAreasColor {
|
||||||
|
Settings::getInstance()->getString("MiximageScreenshotBlankAreasColor")};
|
||||||
|
miximageBlankAreasColor->add("black", "black", selectedBlankAreasColor == "black");
|
||||||
|
miximageBlankAreasColor->add("frame", "frame", selectedBlankAreasColor == "frame");
|
||||||
|
// If there are no objects returned, then there must be a manually modified entry in the
|
||||||
|
// configuration file. Simply set the blank area fill color to "black" in this case.
|
||||||
|
if (miximageBlankAreasColor->getSelectedObjects().size() == 0)
|
||||||
|
miximageBlankAreasColor->selectEntry(0);
|
||||||
|
s->addWithLabel("BLANK AREAS FILL COLOR", miximageBlankAreasColor);
|
||||||
|
s->addSaveFunc([miximageBlankAreasColor, s] {
|
||||||
|
if (miximageBlankAreasColor->getSelected() !=
|
||||||
|
Settings::getInstance()->getString("MiximageScreenshotBlankAreasColor")) {
|
||||||
|
Settings::getInstance()->setString("MiximageScreenshotBlankAreasColor",
|
||||||
|
miximageBlankAreasColor->getSelected());
|
||||||
|
s->setNeedsSaving();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Screenshot scaling method.
|
// Screenshot scaling method.
|
||||||
auto miximageScaling = std::make_shared<OptionListComponent<std::string>>(
|
auto miximageScaling = std::make_shared<OptionListComponent<std::string>>(
|
||||||
getHelpStyle(), "SCREENSHOT SCALING", false);
|
getHelpStyle(), "SCREENSHOT SCALING", false);
|
||||||
|
|
|
@ -121,6 +121,10 @@ void Settings::setDefaults()
|
||||||
mBoolMap["ScrapeManuals"] = {true, true};
|
mBoolMap["ScrapeManuals"] = {true, true};
|
||||||
|
|
||||||
mStringMap["MiximageResolution"] = {"1280x960", "1280x960"};
|
mStringMap["MiximageResolution"] = {"1280x960", "1280x960"};
|
||||||
|
mStringMap["MiximageScreenshotHorizontalFit"] = {"crop", "crop"};
|
||||||
|
mStringMap["MiximageScreenshotVerticalFit"] = {"contain", "contain"};
|
||||||
|
mStringMap["MiximageScreenshotAspectThreshold"] = {"high", "high"};
|
||||||
|
mStringMap["MiximageScreenshotBlankAreasColor"] = {"black", "black"};
|
||||||
mStringMap["MiximageScreenshotScaling"] = {"sharp", "sharp"};
|
mStringMap["MiximageScreenshotScaling"] = {"sharp", "sharp"};
|
||||||
mStringMap["MiximageBoxSize"] = {"medium", "medium"};
|
mStringMap["MiximageBoxSize"] = {"medium", "medium"};
|
||||||
mStringMap["MiximagePhysicalMediaSize"] = {"medium", "medium"};
|
mStringMap["MiximagePhysicalMediaSize"] = {"medium", "medium"};
|
||||||
|
|
|
@ -16,9 +16,9 @@ namespace Utils
|
||||||
cimg_library::CImg<unsigned char>& image)
|
cimg_library::CImg<unsigned char>& image)
|
||||||
{
|
{
|
||||||
// CImg does not interleave pixels as in BGRABGRABGRA so a conversion is required.
|
// CImg does not interleave pixels as in BGRABGRABGRA so a conversion is required.
|
||||||
int counter = 0;
|
int counter {0};
|
||||||
for (int r = 0; r < image.height(); ++r) {
|
for (int r {0}; r < image.height(); ++r) {
|
||||||
for (int c = 0; c < image.width(); ++c) {
|
for (int c {0}; c < image.width(); ++c) {
|
||||||
image(c, r, 0, 0) = imageBGRA[counter + 0];
|
image(c, r, 0, 0) = imageBGRA[counter + 0];
|
||||||
image(c, r, 0, 1) = imageBGRA[counter + 1];
|
image(c, r, 0, 1) = imageBGRA[counter + 1];
|
||||||
image(c, r, 0, 2) = imageBGRA[counter + 2];
|
image(c, r, 0, 2) = imageBGRA[counter + 2];
|
||||||
|
@ -31,8 +31,8 @@ namespace Utils
|
||||||
void convertCImgToBGRA(const cimg_library::CImg<unsigned char>& image,
|
void convertCImgToBGRA(const cimg_library::CImg<unsigned char>& image,
|
||||||
std::vector<unsigned char>& imageBGRA)
|
std::vector<unsigned char>& imageBGRA)
|
||||||
{
|
{
|
||||||
for (int r = image.height() - 1; r >= 0; --r) {
|
for (int r {image.height() - 1}; r >= 0; --r) {
|
||||||
for (int c = 0; c < image.width(); ++c) {
|
for (int c {0}; c < image.width(); ++c) {
|
||||||
imageBGRA.emplace_back((unsigned char)image(c, r, 0, 0));
|
imageBGRA.emplace_back((unsigned char)image(c, r, 0, 0));
|
||||||
imageBGRA.emplace_back((unsigned char)image(c, r, 0, 1));
|
imageBGRA.emplace_back((unsigned char)image(c, r, 0, 1));
|
||||||
imageBGRA.emplace_back((unsigned char)image(c, r, 0, 2));
|
imageBGRA.emplace_back((unsigned char)image(c, r, 0, 2));
|
||||||
|
@ -45,9 +45,9 @@ namespace Utils
|
||||||
cimg_library::CImg<unsigned char>& image)
|
cimg_library::CImg<unsigned char>& image)
|
||||||
{
|
{
|
||||||
// CImg does not interleave pixels as in RGBARGBARGBA so a conversion is required.
|
// CImg does not interleave pixels as in RGBARGBARGBA so a conversion is required.
|
||||||
int counter = 0;
|
int counter {0};
|
||||||
for (int r = 0; r < image.height(); ++r) {
|
for (int r {0}; r < image.height(); ++r) {
|
||||||
for (int c = 0; c < image.width(); ++c) {
|
for (int c {0}; c < image.width(); ++c) {
|
||||||
image(c, r, 0, 0) = imageRGBA[counter + 2];
|
image(c, r, 0, 0) = imageRGBA[counter + 2];
|
||||||
image(c, r, 0, 1) = imageRGBA[counter + 1];
|
image(c, r, 0, 1) = imageRGBA[counter + 1];
|
||||||
image(c, r, 0, 2) = imageRGBA[counter + 0];
|
image(c, r, 0, 2) = imageRGBA[counter + 0];
|
||||||
|
@ -60,8 +60,8 @@ namespace Utils
|
||||||
void convertCImgToRGBA(const cimg_library::CImg<unsigned char>& image,
|
void convertCImgToRGBA(const cimg_library::CImg<unsigned char>& image,
|
||||||
std::vector<unsigned char>& imageRGBA)
|
std::vector<unsigned char>& imageRGBA)
|
||||||
{
|
{
|
||||||
for (int r = image.height() - 1; r >= 0; --r) {
|
for (int r {image.height() - 1}; r >= 0; --r) {
|
||||||
for (int c = 0; c < image.width(); ++c) {
|
for (int c {0}; c < image.width(); ++c) {
|
||||||
imageRGBA.emplace_back((unsigned char)image(c, r, 0, 2));
|
imageRGBA.emplace_back((unsigned char)image(c, r, 0, 2));
|
||||||
imageRGBA.emplace_back((unsigned char)image(c, r, 0, 1));
|
imageRGBA.emplace_back((unsigned char)image(c, r, 0, 1));
|
||||||
imageRGBA.emplace_back((unsigned char)image(c, r, 0, 0));
|
imageRGBA.emplace_back((unsigned char)image(c, r, 0, 0));
|
||||||
|
@ -77,44 +77,44 @@ namespace Utils
|
||||||
if (image.spectrum() != 4)
|
if (image.spectrum() != 4)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
double pixelValueSum = 0.0l;
|
double pixelValueSum {0.0};
|
||||||
int rowCounterTop = 0;
|
int rowCounterTop {0};
|
||||||
int rowCounterBottom = 0;
|
int rowCounterBottom {0};
|
||||||
unsigned int columnCounterLeft = 0;
|
unsigned int columnCounterLeft {0};
|
||||||
unsigned int columnCounterRight = 0;
|
unsigned int columnCounterRight {0};
|
||||||
|
|
||||||
// Count the number of rows and columns that are completely transparent.
|
// Count the number of rows and columns that are completely transparent.
|
||||||
for (int i = image.height() - 1; i > 0; --i) {
|
for (int i {image.height() - 1}; i > 0; --i) {
|
||||||
cimg_library::CImg<unsigned char> imageRow = image.get_rows(i, i);
|
cimg_library::CImg<unsigned char> imageRow = image.get_rows(i, i);
|
||||||
pixelValueSum = imageRow.get_shared_channel(3).sum();
|
pixelValueSum = imageRow.get_shared_channel(3).sum();
|
||||||
if (pixelValueSum == 0.0l)
|
if (pixelValueSum == 0.0)
|
||||||
++rowCounterTop;
|
++rowCounterTop;
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < image.height(); ++i) {
|
for (int i {0}; i < image.height(); ++i) {
|
||||||
cimg_library::CImg<unsigned char> imageRow = image.get_rows(i, i);
|
cimg_library::CImg<unsigned char> imageRow = image.get_rows(i, i);
|
||||||
pixelValueSum = imageRow.get_shared_channel(3).sum();
|
pixelValueSum = imageRow.get_shared_channel(3).sum();
|
||||||
if (pixelValueSum == 0.0l)
|
if (pixelValueSum == 0.0)
|
||||||
++rowCounterBottom;
|
++rowCounterBottom;
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < image.width(); ++i) {
|
for (int i {0}; i < image.width(); ++i) {
|
||||||
cimg_library::CImg<unsigned char> imageColumn = image.get_columns(i, i);
|
cimg_library::CImg<unsigned char> imageColumn = image.get_columns(i, i);
|
||||||
pixelValueSum = imageColumn.get_shared_channel(3).sum();
|
pixelValueSum = imageColumn.get_shared_channel(3).sum();
|
||||||
if (pixelValueSum == 0.0l)
|
if (pixelValueSum == 0.0)
|
||||||
++columnCounterLeft;
|
++columnCounterLeft;
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = image.width() - 1; i > 0; --i) {
|
for (int i {image.width() - 1}; i > 0; --i) {
|
||||||
cimg_library::CImg<unsigned char> imageColumn = image.get_columns(i, i);
|
cimg_library::CImg<unsigned char> imageColumn = image.get_columns(i, i);
|
||||||
pixelValueSum = imageColumn.get_shared_channel(3).sum();
|
pixelValueSum = imageColumn.get_shared_channel(3).sum();
|
||||||
if (pixelValueSum == 0.0l)
|
if (pixelValueSum == 0.0)
|
||||||
++columnCounterRight;
|
++columnCounterRight;
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
|
@ -132,44 +132,44 @@ namespace Utils
|
||||||
if (image.spectrum() != 4)
|
if (image.spectrum() != 4)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
double pixelValueSum = 0.0l;
|
double pixelValueSum {0.0};
|
||||||
int rowCounterTop = 0;
|
int rowCounterTop {0};
|
||||||
int rowCounterBottom = 0;
|
int rowCounterBottom {0};
|
||||||
unsigned int columnCounterLeft = 0;
|
unsigned int columnCounterLeft {0};
|
||||||
unsigned int columnCounterRight = 0;
|
unsigned int columnCounterRight {0};
|
||||||
|
|
||||||
// Count the number of rows and columns that are completely transparent.
|
// Count the number of rows and columns that are completely transparent.
|
||||||
for (int i = image.height() - 1; i > 0; --i) {
|
for (int i {image.height() - 1}; i > 0; --i) {
|
||||||
cimg_library::CImg<unsigned char> imageRow = image.get_rows(i, i);
|
cimg_library::CImg<unsigned char> imageRow = image.get_rows(i, i);
|
||||||
pixelValueSum = imageRow.get_shared_channel(3).sum();
|
pixelValueSum = imageRow.get_shared_channel(3).sum();
|
||||||
if (pixelValueSum == 0.0l)
|
if (pixelValueSum == 0.0)
|
||||||
++rowCounterTop;
|
++rowCounterTop;
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < image.height(); ++i) {
|
for (int i {0}; i < image.height(); ++i) {
|
||||||
cimg_library::CImg<unsigned char> imageRow = image.get_rows(i, i);
|
cimg_library::CImg<unsigned char> imageRow = image.get_rows(i, i);
|
||||||
pixelValueSum = imageRow.get_shared_channel(3).sum();
|
pixelValueSum = imageRow.get_shared_channel(3).sum();
|
||||||
if (pixelValueSum == 0.0l)
|
if (pixelValueSum == 0.0)
|
||||||
++rowCounterBottom;
|
++rowCounterBottom;
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < image.width(); ++i) {
|
for (int i {0}; i < image.width(); ++i) {
|
||||||
cimg_library::CImg<unsigned char> imageColumn = image.get_columns(i, i);
|
cimg_library::CImg<unsigned char> imageColumn = image.get_columns(i, i);
|
||||||
pixelValueSum = imageColumn.get_shared_channel(3).sum();
|
pixelValueSum = imageColumn.get_shared_channel(3).sum();
|
||||||
if (pixelValueSum == 0.0l)
|
if (pixelValueSum == 0.0)
|
||||||
++columnCounterLeft;
|
++columnCounterLeft;
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = image.width() - 1; i > 0; --i) {
|
for (int i {image.width() - 1}; i > 0; --i) {
|
||||||
cimg_library::CImg<unsigned char> imageColumn = image.get_columns(i, i);
|
cimg_library::CImg<unsigned char> imageColumn = image.get_columns(i, i);
|
||||||
pixelValueSum = imageColumn.get_shared_channel(3).sum();
|
pixelValueSum = imageColumn.get_shared_channel(3).sum();
|
||||||
if (pixelValueSum == 0.0l)
|
if (pixelValueSum == 0.0)
|
||||||
++columnCounterRight;
|
++columnCounterRight;
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
|
@ -191,27 +191,27 @@ namespace Utils
|
||||||
|
|
||||||
void cropLetterboxes(cimg_library::CImg<unsigned char>& image)
|
void cropLetterboxes(cimg_library::CImg<unsigned char>& image)
|
||||||
{
|
{
|
||||||
double pixelValueSum = 0.0l;
|
double pixelValueSum {0.0};
|
||||||
int rowCounterUpper = 0;
|
int rowCounterUpper {0};
|
||||||
int rowCounterLower = 0;
|
int rowCounterLower {0};
|
||||||
|
|
||||||
// Count the number of rows that are pure black.
|
// Count the number of rows that are pure black.
|
||||||
for (int i = image.height() - 1; i > 0; --i) {
|
for (int i {image.height() - 1}; i > 0; --i) {
|
||||||
cimg_library::CImg<unsigned char> imageRow = image.get_rows(i, i);
|
cimg_library::CImg<unsigned char> imageRow = image.get_rows(i, i);
|
||||||
// Ignore the alpha channel.
|
// Ignore the alpha channel.
|
||||||
imageRow.channels(0, 2);
|
imageRow.channels(0, 2);
|
||||||
pixelValueSum = imageRow.sum();
|
pixelValueSum = imageRow.sum();
|
||||||
if (pixelValueSum == 0.0l)
|
if (pixelValueSum == 0.0)
|
||||||
++rowCounterUpper;
|
++rowCounterUpper;
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < image.height(); ++i) {
|
for (int i {0}; i < image.height(); ++i) {
|
||||||
cimg_library::CImg<unsigned char> imageRow = image.get_rows(i, i);
|
cimg_library::CImg<unsigned char> imageRow = image.get_rows(i, i);
|
||||||
imageRow.channels(0, 2);
|
imageRow.channels(0, 2);
|
||||||
pixelValueSum = imageRow.sum();
|
pixelValueSum = imageRow.sum();
|
||||||
if (pixelValueSum == 0.0l)
|
if (pixelValueSum == 0.0)
|
||||||
++rowCounterLower;
|
++rowCounterLower;
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
|
@ -227,27 +227,27 @@ namespace Utils
|
||||||
|
|
||||||
void cropPillarboxes(cimg_library::CImg<unsigned char>& image)
|
void cropPillarboxes(cimg_library::CImg<unsigned char>& image)
|
||||||
{
|
{
|
||||||
double pixelValueSum = 0.0l;
|
double pixelValueSum {0.0};
|
||||||
unsigned int columnCounterLeft = 0;
|
unsigned int columnCounterLeft {0};
|
||||||
unsigned int columnCounterRight = 0;
|
unsigned int columnCounterRight {0};
|
||||||
|
|
||||||
// Count the number of columns that are pure black.
|
// Count the number of columns that are pure black.
|
||||||
for (int i = 0; i < image.width(); ++i) {
|
for (int i {0}; i < image.width(); ++i) {
|
||||||
cimg_library::CImg<unsigned char> imageColumn = image.get_columns(i, i);
|
cimg_library::CImg<unsigned char> imageColumn = image.get_columns(i, i);
|
||||||
// Ignore the alpha channel.
|
// Ignore the alpha channel.
|
||||||
imageColumn.channels(0, 2);
|
imageColumn.channels(0, 2);
|
||||||
pixelValueSum = imageColumn.sum();
|
pixelValueSum = imageColumn.sum();
|
||||||
if (pixelValueSum == 0.0l)
|
if (pixelValueSum == 0.0)
|
||||||
++columnCounterLeft;
|
++columnCounterLeft;
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = image.width() - 1; i > 0; --i) {
|
for (int i {image.width() - 1}; i > 0; --i) {
|
||||||
cimg_library::CImg<unsigned char> imageColumn = image.get_columns(i, i);
|
cimg_library::CImg<unsigned char> imageColumn = image.get_columns(i, i);
|
||||||
imageColumn.channels(0, 2);
|
imageColumn.channels(0, 2);
|
||||||
pixelValueSum = imageColumn.sum();
|
pixelValueSum = imageColumn.sum();
|
||||||
if (pixelValueSum == 0.0l)
|
if (pixelValueSum == 0.0)
|
||||||
++columnCounterRight;
|
++columnCounterRight;
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue