sk_sp<SkImageFilter> FEConvolveMatrix::createImageFilter() { if (!parametersValid()) return createTransparentBlack(); sk_sp<SkImageFilter> input( SkiaImageFilterBuilder::build(inputEffect(0), operatingColorSpace())); SkISize kernelSize( SkISize::Make(m_kernelSize.width(), m_kernelSize.height())); // parametersValid() above checks that the kernel area fits in int. int numElements = safeCast<int>(m_kernelSize.area()); SkScalar gain = SkFloatToScalar(1.0f / m_divisor); SkScalar bias = SkFloatToScalar(m_bias * 255); SkIPoint target = SkIPoint::Make(m_targetOffset.x(), m_targetOffset.y()); SkMatrixConvolutionImageFilter::TileMode tileMode = toSkiaTileMode(m_edgeMode); bool convolveAlpha = !m_preserveAlpha; std::unique_ptr<SkScalar[]> kernel = wrapArrayUnique(new SkScalar[numElements]); for (int i = 0; i < numElements; ++i) kernel[i] = SkFloatToScalar(m_kernelMatrix[numElements - 1 - i]); SkImageFilter::CropRect cropRect = getCropRect(); return SkMatrixConvolutionImageFilter::Make( kernelSize, kernel.get(), gain, bias, target, tileMode, convolveAlpha, std::move(input), &cropRect); }
void ConvolutionShader::setKernelRadius(int value) { DPTR_D(ConvolutionShader); if (d.radius == value) return; d.radius = value; d.kernel.resize(kernelSize()); d.updateShaderCode(); }
void GaborFilter::createKernels(int kernelRadius, float wavelength, float aspectRatio, const std::vector<float>& bandwidths, const std::vector<float>& orientations, const std::vector<float>& phases) { this->kernelRadius = kernelRadius; std::vector<float> sigmas; for (int b = 0; b < (int) bandwidths.size(); ++b) { float sigma = (wavelength / CV_PI) * sqrt(log(2.) / 2) * ((pow(2, bandwidths[b]) + 1) / (pow(2, bandwidths[b]) - 1)); sigmas.push_back(sigma); } kernels.resize(orientations.size() * sigmas.size() * phases.size()); cv::Mat kernel; cv::Size kernelSize(2 * kernelRadius + 1, 2 * kernelRadius + 1); int count = 0; for (int s = 0; s < (int) sigmas.size(); ++s) { int radius = sigmas[s]; float variance = sigmas[s] * sigmas[s]; kernel.create(radius * 2 + 1, radius * 2 + 1, CV_32F); for (int o = 0; o < (int) orientations.size(); ++o) { for (int p = 0; p < (int) phases.size(); ++p) { for (int y = -radius; y <= radius; ++y) { float* kernelPtr = kernel.ptr<float> (radius - y); for (int x = -radius; x <= radius; ++x) { float xRot = x * cos(orientations[o]) + y * sin(orientations[o]); float yRot = -x * sin(orientations[o]) + y * cos(orientations[o]); float gaussian = exp(-(xRot * xRot + aspectRatio * aspectRatio * yRot * yRot) / (2 * variance)); float sinusoid = cos(2 * CV_PI * (xRot / wavelength) + phases[p]); kernelPtr[x + radius] = gaussian * sinusoid; } } cv::resize(kernel, kernels[count], kernelSize); ++count; } } } }
PassRefPtr<SkImageFilter> FEConvolveMatrix::createImageFilter(SkiaImageFilterBuilder* builder) { RefPtr<SkImageFilter> input(builder->build(inputEffect(0), operatingColorSpace())); SkISize kernelSize(SkISize::Make(m_kernelSize.width(), m_kernelSize.height())); int numElements = kernelSize.width() * kernelSize.height(); SkScalar gain = SkFloatToScalar(1.0f / m_divisor); SkScalar bias = SkFloatToScalar(m_bias * 255); SkIPoint target = SkIPoint::Make(m_targetOffset.x(), m_targetOffset.y()); SkMatrixConvolutionImageFilter::TileMode tileMode = toSkiaTileMode(m_edgeMode); bool convolveAlpha = !m_preserveAlpha; OwnPtr<SkScalar[]> kernel = adoptArrayPtr(new SkScalar[numElements]); for (int i = 0; i < numElements; ++i) kernel[i] = SkFloatToScalar(m_kernelMatrix[numElements - 1 - i]); SkImageFilter::CropRect cropRect = getCropRect(builder->cropOffset()); return adoptRef(SkMatrixConvolutionImageFilter::Create(kernelSize, kernel.get(), gain, bias, target, tileMode, convolveAlpha, input.get(), &cropRect)); }
void ConvolutionShader::setKernelUniformValue() { program()->setUniformValueArray("u_Kernel", kernel(), kernelSize(), 1); }