#include "ppm_image.h"
#include <algorithm>
#include <array>
#include <cmath>
#include <iostream>
#include <string_view>
using namespace std;
int Sum(img_lib::Color c) {
return to_integer<int>(c.r) + to_integer<int>(c.g) + to_integer<int>(c.b);
}
// реализуйте оператор Собеля
img_lib::Image Sobel(const img_lib::Image& image)
{
const int w = image.GetWidth(),
h = image.GetHeight(),
ih = h - 1,
iw = w - 1;
img_lib::Image im(w, h, img_lib::Color::Black());
for (int y = 0; y < h; ++y) {
auto line = im.GetLine(y);
if (y == 0 or y == ih)
fill(line, line + w, img_lib::Color::Black());
else
for (int x = 0; x < w; ++x)
if (x == 0 or x == iw)
line[x] = img_lib::Color::Black();
else {
const int tl = Sum(image.GetPixel(x - 1, y - 1)),
tc = Sum(image.GetPixel(x, y - 1)),
tr = Sum(image.GetPixel(x + 1, y - 1)),
cl = Sum(image.GetPixel(x - 1, y)),
cr = Sum(image.GetPixel(x + 1, y)),
bl = Sum(image.GetPixel(x - 1, y + 1)),
bc = Sum(image.GetPixel(x, y + 1)),
br = Sum(image.GetPixel(x + 1, y + 1));
int gx = - tl - 2 * tc - tr + bl + 2 * bc + br,
gy = - tl - 2 * cl - bl + tr + 2 * cr + br;
double r = sqrt(gx * gx + gy * gy);
r = clamp(r, 0., 255.);
line[x].r = static_cast<byte>(r);
line[x].g = static_cast<byte>(r);
line[x].b = static_cast<byte>(r);
}
}
return im;
}
int main(int argc, const char** argv) {
if (argc != 3) {
cerr << "Usage: "sv << argv[0] << " <input image> <output image>"sv << endl;
return 1;
}
auto image = img_lib::LoadPPM(argv[1]);
if (!image) {
cerr << "Error loading image"sv << endl;
return 2;
}
image = Sobel(image);
if (!img_lib::SavePPM(argv[2], image)) {
cerr << "Error saving image"sv << endl;
return 3;
}
cout << "Image saved successfully!"sv << endl;
}