我想在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;
}