将灰度设置为ppm图像

时间:2017-01-06 21:35:35

标签: c++

我想在ppm图像中放置灰色过滤器,但是当我运行程序时,我得到了:抛出异常:读取访问冲突。我认为问题出在setPixel方法中(因为我使用了vec3类的operator =因为在它抛出异常之后,程序每次都向我显示operator =方法)。无论如何,我无法找到完全错误的地方,所以我将不胜感激任何帮助。提前谢谢。

Vec3.class

namespace math

{
/*! Represents a triplet of values of the same type S.
 *
 *  The Vec3 class is used as a generic three-dimensional vector and thus it defines several
 *  numerical operators that can be used on Vec3<S> and S data.
 */
template <typename S>
class Vec3
{
public:
    // data members

    //! The first coordinate of the vector
    union { S x, r; }; 

    //! The second coordinate of the vector
    union { S y, g; }; 

    //! The third coordinate of the vector
    union { S z, b; }; 

    // member functions

    /*! Data access operator.
     * 
     *  \param index is the zero-based index to the elements of the vector. No bounds checking is performed for performance reasons.
     *
     *  \return the index-th element of the vector.
     */
    S & operator [] (size_t index)
    {
        return *((S*)this + index);
    }

    /*! Vector addition.
     *
     * \param right is the right-hand vector operand of the addition.
     *
     * \return a new vector that is the component-wise sum of the current and the right vectors.
     */
    Vec3<S> operator + (const Vec3<S> & right)
    {
        Vec3<S> left;
        left.x = x + right.x;
        left.y = y + right.y;
        left.z = z + right.z;
        return left;
    }

    /*! Vector subtraction.
    *
    * \param right is the right-hand vector operand of the subtraction
    *
    * \return a new vector that is the component-wise subtraction of the current and the right vectors.
    */
    Vec3<S> operator - (const Vec3<S> & right)
    {
        Vec3<S> left;
        left.x = x - right.x;
        left.y = y - right.y;
        left.z = z - right.z;
        return left;
    }

    /*! Component-wise vector multiplication.
    *
    * \param right is the right-hand vector operand of the multiplication
    *
    * \return a new vector whose elements are the component-wise multiplied elements of the current and the right vectors.
    */
    Vec3<S> operator * (const Vec3<S> & right)
    {
        Vec3<S> left;
        left.x = x * right.x;
        left.y = y * right.y;
        left.z = z * right.z;
        return left;
    }

    /*! Vector-scalar multiplication.
    *
    * \param right is the right-hand scalar operand of the multiplication
    *
    * \return a new vector whose elements are the elements of the current vector multiplied with the right operand.
    */
    Vec3<S> operator * (S right)
    {
        Vec3<S> left;
        left.x = x * right;
        left.y = y * right;
        left.z = z * right;
        return left;
    }

    /*! Scalar division.
    *
    * No checks are made for zero divisor.
    *
    * \param right is the scalar divisor. 
    *
    * \return a new vector whose elements are the elements of the current vector divided by the right operand.
    */
    Vec3<S> operator / (S right)
    {
        Vec3<S> left;
        left.x = x / right;
        left.y = y / right;
        left.z = z / right;
        return left;
    }

    /*! Component-wise vector division.
    *
    * No checks are made for zero divisor elements.
    *
    * \param right is the vector divisor.
    *
    * \return a new vector whose elements are the elements of the current vector divided by the corresponding elements of the right operand.
    */
    Vec3<S> operator / (const Vec3<S> & right)
    {
        Vec3<S> left;
        left.x = x / right.x;
        left.y = y / right.y;
        left.z = z / right.z;
        return left;
    }

    /*! Addition assignment.
    *
    * \param right is the vector to add to the current one.
    *
    * \return a reference to the current vector after the change.
    */
    Vec3<S> & operator += (const Vec3<S> & right)
    {
        x += right.x;
        y += right.y;
        z += right.z;
        return *this;
    }

    /*! Subtraction assignment
    *
    * \param right is the vector to subtract from the current one.
    *
    * \return a reference to the current vector after the change.
    */
    Vec3<S> & operator -= (const Vec3<S> & right)
    {
        x -= right.x;
        y -= right.y;
        z -= right.z;
        return *this;
    }

    /*! Division assignment using a vector divisor.
    *
    * \param right is the vector divisor.
    *
    * \return a reference to the current vector after the change.
    */
    Vec3<S> & operator /= (const Vec3<S> & right)
    {
        x /= right.x;
        y /= right.y;
        z /= right.z;
        return *this;
    }

    /*! Multiplication assignment using a vector multiplier.
    *
    * \param right is the vector multiplier.
    *
    * \return a reference to the current vector after the change.
    */
    Vec3<S> & operator *= (const Vec3<S> & right)
    {
        x *= right.x;
        y *= right.y;
        z *= right.z;
        return *this;
    }

    /*! Multiplication assignment using a scalar multiplier.
    *
    * \param right is the scalar multiplier.
    *
    * \return a reference to the current vector after the change.
    */
    Vec3<S> & operator *= (S right)
    {
        x *= right;
        y *= right;
        z *= right;
        return *this;
    }

    /*! Division assignment using a scalar divisor.
    *
    * \param right is the scalar divisor.
    *
    * \return a reference to the current vector after the change.
    */
    Vec3<S> & operator /= (S right)
    {
        x /= right;
        y /= right;
        z /= right;
        return *this;
    }

    // constructors

    /*! Constructor with three-element initialization.
     *
     * \param x is the value of th first element.
     * \param y is the value of the second element.
     * \param z is the value of the third element.
     */
    Vec3<S>(S x, S y, S z) : x(x), y(y), z(z) {}

    /*! Constructor with single-element initialization.
    *
    * \param val is the value that is replicated to all elements of the vector.
    */
    Vec3<S>(S val) : x(val), y(val), z(val) {}

    /*! Default constructor.
     * 
     * Initializes all elements to their default numerical value.
     */
    Vec3<S>() : x(), y(), z() {}

    /*! Copy constructor constructor.
     */
    Vec3<S>(const Vec3<S> & right) : x(right.x), y(right.y), z(right.z) {}

    // asignment and equality


    /*! Copy assignment operator. 
    *
    * \param right is the vector to copy.
    *
    * \return a reference to the current vector after the assignment.
    */
    Vec3<S> & operator = (const Vec3<S> & right)
    {
        x = right.x;
        y = right.y;
        z = right.z;
        return *this;
    }

  };

} // namespace math

SetPixel方法

void Image::setPixel(unsigned int x, unsigned int y, Vec3<float> & value) {
    if ((x <= width) && (y <= height) && (x*y >= 0)) {
           int pos = (x + y * width) * 3;
            Vec3<float> vec;
            vec = buffer[pos];
            vec[RED] = value.x;
            vec[GREEN] = value.y;
            vec[BLUE] = value.z;
    }
    else {
        cout << "Width or heigth out of bounds!" << endl;
    }
}

设置过滤器

Image  setGrayFilter(Image & img) {
        float value;
        for (int i = 0; i <img.getWidth(); i++) {
            for (int j = 0; j < img.getHeight(); j++) {
                Vec3<float> vec1 = img.getPixel(i, j);
                value = (vec1[0] + vec1[1] + vec1[2]) / 3;
                Vec3<float> vec2(value, value, value);
                img.setPixel(i, j, vec2);
             }
        }
        return img; 
    }

0 个答案:

没有答案