( ) - libPNG , png_set_background:
-, png_set_background(), . png_set_strip_alpha(), - .
png_set_background(png_ptr, &background_color,
PNG_BACKGROUND_GAMMA_SCREEN, 0, 1);
background_color - RGB libpng .
, OpenCV libPNG , - ( imread).
, libPNG .
, BGRA -. , , Gabriel, .
void remove_transparency(cv::Mat const& source
, cv::Mat& destination
, uint8_t background_color)
{
CV_Assert(source.type() == CV_8UC4);
destination.create(source.rows, source.cols, CV_8UC1);
auto it_src(source.begin<cv::Vec4b>()), it_src_end(source.end<cv::Vec4b>());
auto it_dest(destination.begin<uint8_t>());
std::transform(it_src, it_src_end, it_dest
, [background_color](cv::Vec4b const& v) -> uchar
{
float gray(v[0] * 0.114f + v[1] * 0.587f + v[2] * 0.299f);
float alpha(v[3] / 255.0f);
return cv::saturate_cast<uchar>(gray * alpha + background_color * (1 - alpha));
}
);
}
, , cv::parallel_for_, .
class ParallelRemoveTransparency
: public cv::ParallelLoopBody
{
public:
ParallelRemoveTransparency(cv::Mat const& source
, cv::Mat& destination
, uint8_t background_color)
: source_(source)
, destination_(destination)
, background_color_(background_color)
{
CV_Assert(source.size == destination.size);
}
virtual void operator()(const cv::Range& range) const
{
cv::Mat4b roi_src(source_.rowRange(range));
cv::Mat1b roi_dest(destination_.rowRange(range));
std::transform(roi_src.begin(), roi_src.end(), roi_dest.begin()
, [this](cv::Vec4b const& v) -> uint8_t {
float gray(v[0] * 0.114f + v[1] * 0.587f + v[2] * 0.299f);
float alpha(v[3] / 255.0f);
return cv::saturate_cast<uint8_t>(gray * alpha + background_color_ * (1 - alpha));
}
);
}
private:
cv::Mat const& source_;
cv::Mat& destination_;
uint8_t background_color_;
};
void remove_transparency(cv::Mat const& source
, cv::Mat& destination
, uint8_t background_color)
{
CV_Assert(source.type() == CV_8UC4);
destination.create(source.rows, source.cols, CV_8UC1);
ParallelRemoveTransparency parallel_impl(source, destination, background_color);
cv::parallel_for_(cv::Range(0, source.rows), parallel_impl);
}
, Python. :
import numpy as np
import cv2
def remove_transparency(source, background_color):
source_img = cv2.cvtColor(source[:,:,:3], cv2.COLOR_BGR2GRAY)
source_mask = source[:,:,3] * (1 / 255.0)
background_mask = 1.0 - source_mask
bg_part = (background_color * (1 / 255.0)) * (background_mask)
source_part = (source_img * (1 / 255.0)) * (source_mask)
return np.uint8(cv2.addWeighted(bg_part, 255.0, source_part, 255.0, 0.0))
img = cv2.imread('smile.png', -1)
result = remove_transparency(img, 255)
cv2.imshow('', result)
cv2.waitKey()