PixelBuffer * Filter::generateFilteredBuffer(const PixelBuffer & input_buffer) { PixelBuffer * output_buffer = new PixelBuffer(input_buffer.getWidth(), input_buffer.getHeight(), input_buffer.getBackground()); for (int i = 0; i < input_buffer.getWidth(); i++) { for (int j = 0; j < input_buffer.getHeight(); j++) { ColorData p = generatePixel(input_buffer, i, j); output_buffer->setPixel(i, j, p.clampedColor()); } } return output_buffer; }
// Default implementation of 2D convolution void ConvolutionTool::applyToolOnCanvas(PixelBuffer* pixel_buffer){ // check if the tool mask is valid if(m_mask == NULL){ cerr << "[ConvolutionTool] mask is null" << endl; return; } // Dimensions of the canvas and mask int width = pixel_buffer->getWidth(); int height = pixel_buffer->getHeight(); int mw = m_mask->getWidth(); int mh = m_mask->getHeight(); // Coordinates to access the canvas int posx,posy; // Declare variable to store intermediate results ColorData tmp; PixelBuffer tmpPb(width,height, ColorData(0.0,0.0,0.0)); // 2D Convolution for(int x = 0; x < width; x++){ for(int y = 0; y < height; y++){ tmp = ColorData(0.0,0.0,0.0); // Multiply every value of the mask a corresponding image pixel for(int mx = 0; mx < mw; mx++){ for(int my = 0; my < mh; my++){ posx = (x - mw / 2 + mx); posy = (y - mh / 2 + my); // If trying to access out of bounds indicies, skip if(posx < 0 || posy < 0 || posx >= width || posy >= height) continue; // Accumulate values tmp = tmp + (pixel_buffer->getPixel(posx,posy) * m_mask->getValue(mx,my)); } } tmpPb.setPixel(x,y,tmp.clampedColor()); } } // Set result PixelBuffer::copyPixelBuffer(&tmpPb,pixel_buffer); }
///apply filter effect to the PixelBuffer* buffer passed into this function void FBlur::applyFilter(PixelBuffer* imageBuffer){ // if kernel is already initialized, do not need initialize it again. kernel = buildKernel(std::round(getFloatParameter())); // printKernel(); if(getName() == "FEdgeDetection"){ imageBuffer -> convertToLuminance(); } int width = imageBuffer -> getWidth(); int height = imageBuffer -> getHeight(); //create a new pixel buffer for storing the convolution result. PixelBuffer* newImageBuffer = new PixelBuffer(width, height, imageBuffer -> getBackgroundColor()); for(int i = 0; i < width; i++){ for(int j = 0; j < height; j++){ float newRed = 0; float newGreen = 0; float newBlue = 0; for(size_t filterI = 0; filterI < kernel.size(); filterI++){ for(size_t filterJ = 0; filterJ < kernel[filterI].size(); filterJ++){ //The location imageI and imageJ is calculated so that //for the center element of the filter it'll be i, j int imageI = (i - kernel.size()/2 + filterI + width) % width; int imageJ = (j - kernel[filterI].size()/2 + filterJ + height) % height; ColorData currPixel = imageBuffer -> getPixel(imageI, imageJ); newRed += currPixel.getRed() * kernel[filterI][filterJ]; newGreen += currPixel.getGreen()*kernel[filterI][filterJ]; newBlue += currPixel.getBlue()*kernel[filterI][filterJ]; } } ColorData newPixel = ColorData(newRed, newGreen, newBlue); newPixel = newPixel.clampedColor(); newImageBuffer -> setPixel(i, j, newPixel); } } newImageBuffer -> copyPixelBuffer(newImageBuffer, imageBuffer); delete newImageBuffer; }