#include "StdAfx.h" #include "ImageMatQueue.h" #include "PublicFunc.h" #include "ImageProcess/ImageApplyHeaders.h" #include "ImageMultiOutput.h" #include "jpeglib.h" #include "filetools.h" #include using namespace cv; using namespace std; #define DECODE_COLOR_BGR 1 #define DECODE_GRAY 6 G200Decode::G200Decode(std::shared_ptr> buff) { const int int_buffer_size = 1024; int buffer_size = buff->size(); int b_buffer_size = 0; int f_buffer_size = 0; std::shared_ptr> buffB(new std::vector(buff->size())); std::shared_ptr> buffF(new std::vector(buff->size()));; unsigned char* bbuf = (unsigned char*)(buffB->data()); unsigned char* fbuf = (unsigned char*)(buffF->data()); unsigned char* buf = (unsigned char*)(buff->data()); for (int i = 0; i < (buffer_size / int_buffer_size); i++) { if (buf[(i + 1) * int_buffer_size - 1] == 0) { memcpy(bbuf + b_buffer_size, buf + i * int_buffer_size, int_buffer_size - 1); b_buffer_size += (int_buffer_size - 1); } else if (buf[(i + 1) * int_buffer_size - 1] == 255) { memcpy(fbuf + f_buffer_size, buf + i * int_buffer_size, int_buffer_size - 1); f_buffer_size += (int_buffer_size - 1); } } buffB->resize(b_buffer_size); buffF->resize(f_buffer_size); m_buffs.push_back(buffB); m_buffs.push_back(buffF); } ImageMatQueue::ImageMatQueue(void) : bRun(false) , is_scanning(false) { atm_orgin_image_remains = 0; } void ImageMatQueue::run() { if (!m_threadProc) { bRun = true; m_threadProc.reset(new thread(&ImageMatQueue::proc, this)); } } int ImageMatQueue::orginimgcount() { return atm_orgin_image_remains; } ImageMatQueue::~ImageMatQueue(void) { m_rawBuffs.Clear(); m_imagedata.Clear(); m_rawBuffs.ShutDown(); m_imagedata.ShutDown(); if (m_threadProc) { bRun = false; m_threadProc->join(); m_threadProc.reset(); } } void ImageMatQueue::pushMat(std::shared_ptr data) { std::lock_guard lock(m_mtxJB); m_rawBuffs.Put(data); atm_orgin_image_remains++; } std::vector ImageMatQueue::popBmpdata() { std::lock_guard lock(m_mtxJB); std::vector retdata = m_imagedata.Take(); return retdata; } bool ImageMatQueue::valid() { return m_imagedata.Size(); } void ImageMatQueue::clear() { m_rawBuffs.Clear(); m_imagedata.Clear(); atm_orgin_image_remains = 0; } void ImageMatQueue::setparam(const GScanCap& param) { scanParam = param; m_iaList.clear(); if (scanParam.fillhole.is_fillhole) { float ratio = scanParam.fillhole.fillholeratio/100.0; m_iaList.push_back(shared_ptr(new CImageOutHole(200, ratio, 50))); } //确保能够获取正反两面图 { bool islongcustomcrop = false; if (param.papertype == TwSS::USStatement) islongcustomcrop = true; CSize fixedSize = papersize.GetPaperSize(param.papertype, 200.0f, param.paperAlign); m_iaList.push_back(shared_ptr(new CImageApplyAutoCrop(islongcustomcrop ? islongcustomcrop : param.is_autocrop, param.autodescrew, param.fillbackground, cv::Size(fixedSize.cx, fixedSize.cy), true))); } if (param.is_autodiscradblank_normal || param.is_autodiscradblank_vince) { m_iaList.push_back(shared_ptr(new CImageApplyDiscardBlank(param.is_autodiscradblank_normal ? true : false))); //m_iaList.push_back(shared_ptr(new CImageApplyDiscardBlank(param.areanum,param.devnmax))); } //if (param.pixtype != 0) //sharpen // m_iaList.push_back(shared_ptr(new CImageApplySharpen())); //filter 0 r 1 g 2 b 3 none enhance color 0 none 1 r 2 g 3 b if (param.filter != 3 || param.enhance_color) { int channel = 0; //filter none r g b enhance none r g b if (param.filter != 3) { channel = param.filter; } else { channel = param.enhance_color + 3; } m_iaList.push_back(shared_ptr(new CImageApplyChannel(static_cast(channel)))); } if (param.brightness != 0 || param.contrast != 0 || param.gamma != 1.0) { double aa = (254.0 / 2000.0) * param.brightness + 0.5; int bright = ceil(aa);//[-127,128] 0.128=256.0/2000.0 int contrast = (int)(param.contrast * 0.036);//[-36,36] 0.036=72.0/2000.0; m_iaList.push_back(shared_ptr(new CImageApplyAdjustColors(bright, contrast, param.gamma))); } if (param.pixtype == 0) //threshold m_iaList.push_back(shared_ptr(new CImageApplyBWBinaray(CImageApplyBWBinaray::ThresholdType::THRESH_BINARY))); if (param.sharpen) { SharpenBlur sb = (SharpenBlur)param.sharpen; m_iaList.push_back(shared_ptr(new CImageApplySharpen(sb))); } if (param.resolution_dst != 200.0) { CImageApplyResize* apply; bool islongcustomcrop = false; if (param.papertype == TwSS::USStatement) islongcustomcrop = true; if (param.is_autocrop|| islongcustomcrop) { double ratio = param.resolution_dst / 200.0; apply = new CImageApplyResize(CImageApplyResize::ResizeType::RATIO, cv::Size(0, 0), ratio, ratio); } else { CSize dSize = papersize.GetPaperSize(param.papertype, param.resolution_dst, param.paperAlign); apply = new CImageApplyResize(CImageApplyResize::ResizeType::DSIZE, cv::Size(dSize.cx, dSize.cy), 1.0, 1.0); } m_iaList.push_back(shared_ptr< CImageApply>(apply)); } if (param.imageRotateDegree != 0.0 || param.is_backrotate180 || param.is_autotext) { CImageApplyRotation::RotationType type; if (param.imageRotateDegree > 89.0f && param.imageRotateDegree < 91.0f) type = CImageApplyRotation::RotationType::Rotate_90_clockwise; else if (param.imageRotateDegree > 269.0f && param.imageRotateDegree < 271.0f) type = CImageApplyRotation::RotationType::Rotate_90_anti_clockwise; else if (param.imageRotateDegree > 179.0f && param.imageRotateDegree < 181.0f) type = CImageApplyRotation::RotationType::Rotate_180; else type = CImageApplyRotation::RotationType::Invalid; if (param.is_autotext) type = CImageApplyRotation::RotationType::AutoTextOrientation; TCHAR szIniFile[MAX_PATH] = { 0 }; SHGetSpecialFolderPath(NULL, szIniFile, CSIDL_WINDOWS, TRUE); _tcscat(szIniFile, _T("\\twain_32\\HuaGoScan\\tessdata")); int iLen = WideCharToMultiByte(CP_ACP, 0, szIniFile, -1, NULL, 0, NULL, NULL); char* chRtn = new char[iLen * sizeof(char)]; WideCharToMultiByte(CP_ACP, 0, szIniFile, -1, chRtn, iLen, NULL, NULL); m_iaList.push_back(shared_ptr(new CImageApplyRotation(type, param.is_backrotate180, param.resolution_dst, chRtn))); delete[] chRtn; } } void ImageMatQueue::EnqueueBmpBuffer(std::vector& bmpdata) { //std::lock_guard lock(m_Locker); m_imagedata.Put(bmpdata); } void ImageMatQueue::PaniusCount() { atm_orgin_image_remains--; } bool ImageMatQueue::empty() { return atm_orgin_image_remains == 0 && m_imagedata.Size() == 0 && !is_scanning; } static int index = 0; void ImageMatQueue::proc() { while (bRun) { while (m_imagedata.Size() > 0) { this_thread::sleep_for(chrono::milliseconds(1)); } if (m_rawBuffs.Size() == 0) { this_thread::sleep_for(chrono::milliseconds(1)); continue; } auto buffs = m_rawBuffs.Take()->getImageBuffs(); if (!m_rawBuffs.IsShutDown() && !buffs.empty()) { vector mats; for (auto& buf : buffs) { ImreadModes rm; if (scanParam.filter != 3 || scanParam.enhance_color) rm = IMREAD_COLOR; else rm = scanParam.pixtype == 2 ? IMREAD_COLOR : IMREAD_GRAYSCALE; cv::Mat mat = cv::imdecode(*buf, rm); if (mat.empty()) { fstream fss; fss.open("D:\\decodeerror.txt", std::ios::out); fss << "decode image data error" << endl; fss.close(); } mats.push_back(mat); } for (int j = 0; j < m_iaList.size(); j++) { m_iaList[j]->apply(mats, scanParam.is_duplex); } for (int i = 0; i < mats.size(); i++) { if (!scanParam.is_duplex && i == 1) { mats[i].release(); break; } if (!mats[i].empty()) { IMat2Bmp idata; idata = scanParam.pixtype == 0 ? (IMat2Bmp)Mat2BmpBw(mats[i], scanParam.resolution_dst) : Mat2Bmp(mats[i]); auto data = idata.getBmpDataBuffer(); EnqueueBmpBuffer(data); } else { FileTools::write_log("emptyimage.txt", "enqueue image is empty " + std::to_string(index++)); } } if (scanParam.multi_output_red) { for (int i = 0; i < mats.size(); i++) { ImageMultiOutput m_mlt; Mat m_filterMat = m_mlt.GetMultiFilterMat(mats[i], 2); if (!m_filterMat.empty()) { if (!scanParam.is_duplex && i == 1) { mats[i].release(); break; } if (!m_filterMat.empty()) { Mat2Bmp mb(m_filterMat); auto data = mb.getBmpDataBuffer(); EnqueueBmpBuffer(data); } } } } PaniusCount(); } } } GRawDecode::GRawDecode(std::shared_ptr> buff) { m_buffs.push_back(buff); }