Closed MaverickTse closed 8 years ago
also convert your Mat to CV_8UC3 at some point before imwrite() if you're not writing to PNG. BTW, do you need transparency at all?
do you need transparency at all?
いいえ。このソフトは透過情報についての処理をする予定はありません。(画面キャプチャーをする時透過情報は不要)
convert your Mat to CV_8UC3
cv::Mat::convertToが(PNG以外には)必要ということですか?つまり
namespace converter {
cv::Mat BITMAP_to_cv_Mat(const BITMAP & img) {
cv::Mat re(img.bmHeight, img.bmWidth, CV_8UC4, img.bmBits,img.bmWidthBytes);
re.convertTo(re, CV_8UC3);
cv::flip(re, re, 0);//上下反転
return re;
}
}
ということ?(pngの判定を除けば)
yes. but in-place format conversion can be dangerous.
in-place format conversion
とは?
memmove
関数みたいな用途(コピー元のメモリー領域とコピー先のメモリー領域が重なっている)のメモリーコピのことですか?
in-place conversion: the converted object occupies the same memory space as the source. but since you are working on a memory block allocated by Windows GDI, you can't guarantee Windows won't touch that memory block. In addition, Mat::convertTo() is a generalized function. To make it works on a variety of format, I bet it copies to a temporary space if it can't find one. In the case of CV_8UC4 → CV_8UC3, it involve shifting bytes, but what if CV_8UC3 → CV_32FC3 ? It MUST allocate a new memory block or will run into access violation. In the end, you can't run away from at least a single new memory allocation. So why not make a copy which we have complete control?
How about this code?
namespace converter {
cv::Mat BITMAP_to_cv_Mat(const BITMAP & img) {
cv::Mat re;
cv::Mat(img.bmHeight, img.bmWidth, CV_8UC4, img.bmBits,img.bmWidthBytes).convertTo(re, CV_8UC3);
cv::flip(re, re, 0);//上下反転
return re;
}
}
cv::Mat src(img.bmHeight, img.bmWidth, CV_8UC4, img.bmBits,img.bmWidthBytes); //no copying here
cv::Mat re;
src.convertTo(re, CV_8UC3); //copy and restructure once here
cv::flip(re, re, 0);
return re;
reject. コメントで出た別の方法で修正済み
https://github.com/yumetodo/Scatto_continuo_v3/commit/f26c18c7728d991f03b3fe1167b91899f9e7621d
Depending on OpenCV build customization, encoding to formats other than BMP may not work.