Покритикуйте библиотеку для работы с изображениями
От: syomin  
Дата: 05.09.07 16:00
Оценка:
Добрый день! Заранее извиняюсь за объем сообщения, сокращал как мог.

Возникла задача разработать библиотеку на языке C++ для обработки растровых изображений. Специфика задачи такова, что приходится иметь дело с различными цветовыми пространствами. Минимум — grayscale и binary, в дальнейшем, возможно, появится RGB.

Для примера смотрел на Qt4, System.Drawing из .Net и java.awt.Graphics.

Все фундаментальные свойства изображений я вынес в отдельный шаблон, который параметризуется типом, который хранит сведения об отдельном пикселе изображения.

template<class T>
class Image {
public:
    // Тип данных, используемый для хранения сведений об отдельном пикселе
    // изображения.
    typedef T Pixel;

    // Конструктор копирования и оператор присваивания.
    Image(const Image &rhs);
    Image<Pixel> &operator=(const Image &rhs);

    // Возвращает true, если ширина и высота изображения равны 0.
    bool isNull() const throw();

    // Получить размеры изображения.
    const Size &getSize() const throw();
    int getWidth() const throw();
    int getHeight() const throw();

    // Получить пиксел с заданными координатами.
    Pixel getPixel(const Point &point) const;
    Pixel getPixel(int x, int y) const;

    // Изменить пиксел с заданными координатами.
    void setPixel(const Point &point, Pixel pixel);
    void setPixel(int x, int y, Pixel pixel);

protected:
    // Конструкторы.
    Image() {}
    explicit Image(const Size &size);
    Image(int width, int height);

private:
    Size size_;
    std::vector<Pixel> pixels_;
};


От него наследуется класс для работы с полутоновыми изображениями:
// Класс "Полутоновое изображение".
class GrayImage : public Image<unsigned char> {
public:
    // Конструкторы.
    GrayImage() {}
    explicit GrayImage(const Size &size) : Image<Pixel>(size) {}
    GrayImage(int width, int height) : Image<Pixel>(width, height) {}
    explicit GrayImage(const std::string &filename);

    // Сохранить изображение в файл.
    void save(const std::string &filename);
};


И почти то же самое делает для бинарных изображений — приводить код не буду, его и так уже много

Что касается классов Point и Size, то выглядят они так:
// Класс, описывающий координаты точки на плоскости.
class Point {
public:
    // Конструкторы.
    Point() throw() : x_(0), y_(0) {}
    Point(int x, int y) throw() : x_(x), y_(y) {}

    // Получить координаты точки.
    int getX() const throw();
    int getY() const throw();

    // Изменить координаты точки.
    void setX(int x) throw();
    void setY(int y) throw();
    void setXY(int x, int y) throw();

    // Декрементировать координаты точки.
    void decX() throw() { --x_; }
    void decY() throw() { --y_; }

    // Инкрементировать координаты точки.
    void incX() throw() { ++x_; }
    void incY() throw() { ++y_; }

private:
    int x_;
    int y_;
};

bool operator==(const Point &lhs, const Point &rhs) throw();
bool operator!=(const Point &lhs, const Point &rhs) throw();


// Класс, описывающий размеры двумерного объекта на плоскости (чаще всего -
// прямоугольника).
class Size {
public:
    // Конструкторы.
    Size() throw() : width_(0), height_(0) {}
    Size(int width, int height) { setSize(width, height); }

    // Возвращает true, если ширина и высота объекта равны 0.
    bool isNull() const throw();

    // Получить размер объекта.
    int getWidth() const throw();
    int getHeight() const throw();

    // Изменить ширину объекта.
    void setWidth(int width);

    // Изменить высоту объекта.
    void setHeight(int height);

    // Изменить размер объекта.
    void setSize(int width, int height);

private:
    int width_;
    int height_;
};

inline bool operator==(const Size &lhs, const Size &rhs) throw();
inline bool operator!=(const Size &lhs, const Size &rhs) throw();


Для тех, кто все-таки добрался до этого места, у меня есть ряд вопросов:
1. Какие есть минусы схемы с наследованием от Image<>? Мне пока ничего такого найти не удалось, поэтому и возникают некоторые сомнения — почему я такого больше нигде не видел?
2. Стоит ли овчинка выделки применительно к классам Point и Size? Может лучше отказаться от них, а при вызове методов Image<> отдельно указывать x и y (или width и height)?
3. Ну и вообще, как вам дизайн?

Заранее благодарю за ответы по существу.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.