#include "HGImgProc.h" #include "./ImageProcess/ImageApplyAdjustColors.h" #include "./ImageProcess/ImageApplyAutoCrop.h" #include "./ImageProcess/ImageApplyDiscardBlank.h" #include "CvxText.hpp" #include "../base/HGInc.h" #include "../base/HGUtility.h" HGResult HGAPI HGImgProc_ResizeImage(HGImage image, HGImage destImage, HGUInt interp) { if (NULL == image || NULL == destImage || image == destImage) { return HGBASE_ERR_INVALIDARG; } if (HGIMGPROC_INTERPOTYPE_NN != interp && HGIMGPROC_INTERPOTYPE_LINEAR != interp) { return HGBASE_ERR_INVALIDARG; } HGImageInfo imgInfo; HGBase_GetImageInfo(image, &imgInfo); HGImageInfo destImgInfo; HGBase_GetImageInfo(destImage, &destImgInfo); uint32_t type = imgInfo.type; uint32_t destType = destImgInfo.type; if (type != destType) { return HGBASE_ERR_INVALIDDATA; } HGByte* data = NULL; HGBase_GetImageData(image, &data); HGByte* destData = NULL; HGBase_GetImageData(destImage, &destData); HGImageRoi roi; HGBase_GetImageROI(image, &roi); HGImageRoi destRoi; HGBase_GetImageROI(destImage, &destRoi); HGUInt roiWidth = roi.right - roi.left; HGUInt roiHeight = roi.bottom - roi.top; HGUInt destRoiWidth = destRoi.right - destRoi.left; HGUInt destRoiHeight = destRoi.bottom - destRoi.top; if (roiWidth == destRoiWidth && roiHeight == destRoiHeight) { return HGBase_CopyImage(image, destImage); } if (HGBASE_IMGTYPE_BINARY == type) { HGImage imageTmp1 = NULL; HGResult ret = HGBase_CloneImage(image, HGBASE_IMGTYPE_GRAY, 0, &imageTmp1); if (HGBASE_ERR_OK == ret) { HGImage imageTmp2 = NULL; ret = HGBase_CreateImage(destRoiWidth, destRoiHeight, HGBASE_IMGTYPE_GRAY, imgInfo.origin, &imageTmp2); if (HGBASE_ERR_OK == ret) { ret = HGImgProc_ResizeImage(imageTmp1, imageTmp2, interp); if (HGBASE_ERR_OK == ret) { ret = HGBase_CopyImage(imageTmp2, destImage); } HGBase_DestroyImage(imageTmp2); } HGBase_DestroyImage(imageTmp1); } return ret; } uint32_t channels = 1; if (HGBASE_IMGTYPE_BGR == type || HGBASE_IMGTYPE_RGB == type) channels = 3; else if (HGBASE_IMGTYPE_BGRA == type || HGBASE_IMGTYPE_RGBA == type) channels = 4; uint8_t* p = data + roi.top * imgInfo.widthStep + roi.left * channels; uint8_t* pDest = destData + destRoi.top * destImgInfo.widthStep + destRoi.left * channels; IplImage* pImg = cvCreateImageHeader(cvSize(roiWidth, roiHeight), IPL_DEPTH_8U, channels); IplImage* pImgDest = cvCreateImageHeader(cvSize(destRoiWidth, destRoiHeight), IPL_DEPTH_8U, channels); cvSetData(pImg, p, imgInfo.widthStep); cvSetData(pImgDest, pDest, destImgInfo.widthStep); int interpolation = (HGIMGPROC_INTERPOTYPE_NN == interp) ? CV_INTER_NN : CV_INTER_LINEAR; cvResize(pImg, pImgDest, interpolation); cvReleaseImageHeader(&pImgDest); cvReleaseImageHeader(&pImg); if (imgInfo.origin != destImgInfo.origin) { HGBase_ImageFlip(destImage, destImage); } return HGBASE_ERR_OK; } HGResult HGAPI HGImgProc_ImageAdjustColors(HGImage image, HGImage destImage, HGInt brightness, HGInt contrast, HGFloat gamma) { if (NULL == image) { return HGBASE_ERR_INVALIDARG; } HGImageInfo imgInfo; HGBase_GetImageInfo(image, &imgInfo); HGUInt type = imgInfo.type; HGByte* data = NULL; HGBase_GetImageData(image, &data); HGImageRoi roi; HGBase_GetImageROI(image, &roi); HGUInt roiWidth = roi.right - roi.left; HGUInt roiHeight = roi.bottom - roi.top; uint32_t channels = 1; if (HGBASE_IMGTYPE_BGR == type || HGBASE_IMGTYPE_RGB == type) channels = 3; else if (HGBASE_IMGTYPE_BGRA == type || HGBASE_IMGTYPE_RGBA == type) channels = 4; if (NULL == destImage || image == destImage) { if (HGBASE_IMGTYPE_BINARY == type) { HGImage imageTmp = NULL; HGResult ret = HGBase_CloneImage(image, HGBASE_IMGTYPE_GRAY, 0, &imageTmp); if (HGBASE_ERR_OK == ret) { ret = HGImgProc_ImageAdjustColors(imageTmp, imageTmp, brightness, contrast, gamma); if (HGBASE_ERR_OK == ret) { ret = HGBase_CopyImage(imageTmp, image); } HGBase_DestroyImage(imageTmp); } return ret; } uint8_t* p = data + roi.top * imgInfo.widthStep + roi.left * channels; cv::Mat img(roiHeight, roiWidth, CV_8UC(channels), p, imgInfo.widthStep); CImageApplyAdjustColors imgApply(brightness, contrast, gamma); imgApply.apply(img, 0); } else { HGImageInfo destImgInfo; HGBase_GetImageInfo(destImage, &destImgInfo); HGUInt destType = destImgInfo.type; if (type != destType) { return HGBASE_ERR_INVALIDDATA; } HGByte* destData = NULL; HGBase_GetImageData(destImage, &destData); HGImageRoi destRoi; HGBase_GetImageROI(destImage, &destRoi); HGUInt destRoiWidth = destRoi.right - destRoi.left; HGUInt destRoiHeight = destRoi.bottom - destRoi.top; if (roiWidth != destRoiWidth || roiHeight != destRoiHeight) { return HGBASE_ERR_INVALIDDATA; } if (HGBASE_IMGTYPE_BINARY == type) { HGImage imageTmp = NULL; HGResult ret = HGBase_CloneImage(image, HGBASE_IMGTYPE_GRAY, 0, &imageTmp); if (HGBASE_ERR_OK == ret) { ret = HGImgProc_ImageAdjustColors(imageTmp, imageTmp, brightness, contrast, gamma); if (HGBASE_ERR_OK == ret) { ret = HGBase_CopyImage(imageTmp, destImage); } HGBase_DestroyImage(imageTmp); } return ret; } HGBase_CopyImage(image, destImage); uint8_t* pDest = destData + destRoi.top * destImgInfo.widthStep + destRoi.left * channels; cv::Mat destImg(destRoiHeight, destRoiWidth, CV_8UC(channels), pDest, destImgInfo.widthStep); CImageApplyAdjustColors imgApply(brightness, contrast, gamma); imgApply.apply(destImg, 0); } return HGBASE_ERR_OK; } HGResult HGAPI HGImgProc_ImageAutoCrop(HGImage image, HGBool autoCrop, HGBool deskew, HGBool fillBlank, const HGImgAutoCropParam* param, HGUInt destWidth, HGUInt destHeight, HGUInt destType, HGUInt destOrigin, HGImage* destImage) { if (NULL == image || NULL == destImage) { return HGBASE_ERR_INVALIDARG; } HGImageInfo imgInfo; HGBase_GetImageInfo(image, &imgInfo); if (HGBASE_IMGTYPE_BINARY == imgInfo.type || HGBASE_IMGTYPE_RGBA == imgInfo.type || HGBASE_IMGTYPE_BGRA == imgInfo.type) { HGImage imageTmp = NULL; HGResult ret = HGBase_CloneImage(image, HGBASE_IMGTYPE_RGB, 0, &imageTmp); if (HGBASE_ERR_OK == ret) { if (0 == destType) destType = imgInfo.type; if (0 == destOrigin) destOrigin = imgInfo.origin; ret = HGImgProc_ImageAutoCrop(imageTmp, autoCrop, deskew, fillBlank, param, destWidth, destHeight, destType, destOrigin, destImage); HGBase_DestroyImage(imageTmp); } return ret; } bool convex = true; bool fillColor = false; double threshold = 40.0; int noise = 8; int indent = 5; bool normalCrop = false; bool dispersion = true; if (NULL != param) { convex = (bool)param->convex; fillColor = (bool)param->fillColor; threshold = param->threshold; noise = param->noise; indent = param->indent; normalCrop = (bool)param->normalCrop; dispersion = (bool)param->dispersion; } HGByte* data = NULL; HGBase_GetImageData(image, &data); HGImageRoi roi; HGBase_GetImageROI(image, &roi); HGUInt roiWidth = roi.right - roi.left; HGUInt roiHeight = roi.bottom - roi.top; uint32_t channels = 1; if (HGBASE_IMGTYPE_RGB == imgInfo.type || HGBASE_IMGTYPE_BGR == imgInfo.type) channels = 3; uint8_t* p = data + roi.top * imgInfo.widthStep + roi.left * channels; cv::Mat img(roiHeight, roiWidth, CV_8UC(channels), p, imgInfo.widthStep); cv::Mat destImg; autoCrop_desaskew_fillBlank(img, destImg, autoCrop, deskew, fillBlank, destWidth, destHeight, convex, fillColor, threshold, noise, indent, normalCrop, dispersion); if (destImg.empty()) { return HGIMGPROC_ERR_FAIL; } HGImageInfo newImgInfo; newImgInfo.width = (HGUInt)destImg.cols; newImgInfo.height = (HGUInt)destImg.rows; newImgInfo.type = imgInfo.type; newImgInfo.widthStep = (HGUInt)destImg.step; newImgInfo.origin = imgInfo.origin; if (0 == destType) destType = imgInfo.type; if (0 == destOrigin) destOrigin = imgInfo.origin; return HGBase_CreateImageFromData(destImg.data, &newImgInfo, NULL, destType, destOrigin, destImage); } HGResult HGAPI HGImgProc_ImageBlankCheck(HGImage image, const HGImgBlankCheckParam* param, HGBool* blank) { if (NULL == image || NULL == blank) { return HGBASE_ERR_INVALIDARG; } HGImageInfo imgInfo; HGBase_GetImageInfo(image, &imgInfo); if (HGBASE_IMGTYPE_BINARY == imgInfo.type || HGBASE_IMGTYPE_RGBA == imgInfo.type || HGBASE_IMGTYPE_BGRA == imgInfo.type) { HGImage imageTmp = NULL; HGResult ret = HGBase_CloneImage(image, HGBASE_IMGTYPE_RGB, 0, &imageTmp); if (HGBASE_ERR_OK == ret) { ret = HGImgProc_ImageBlankCheck(imageTmp, param, blank); HGBase_DestroyImage(imageTmp); } return ret; } HGDouble threshold = 40.0; HGInt edge = 150; HGInt blockSize = 10; HGDouble devTh = 50.0; HGDouble meanTh = 200.0; if (NULL != param) { threshold = param->threshold; edge = param->edge; blockSize = param->blockSize; devTh = param->devTh; meanTh = param->meanTh; } HGByte* data = NULL; HGBase_GetImageData(image, &data); HGImageRoi roi; HGBase_GetImageROI(image, &roi); HGUInt roiWidth = roi.right - roi.left; HGUInt roiHeight = roi.bottom - roi.top; uint32_t channels = 1; if (HGBASE_IMGTYPE_BGR == imgInfo.type || HGBASE_IMGTYPE_RGB == imgInfo.type) channels = 3; uint8_t* p = data + roi.top * imgInfo.widthStep + roi.left * channels; cv::Mat img(roiHeight, roiWidth, CV_8UC(channels), p, imgInfo.widthStep); bool ret = CImageApplyDiscardBlank::apply(img, threshold, edge, blockSize, devTh, meanTh); *blank = ret ? HGTRUE : HGFALSE; return HGBASE_ERR_OK; } static HGResult MeasureString(const HGChar* text, HGInt x, HGInt y, const HGImgWatermarkFontParam* fontParam, HGRect* pos) { assert(NULL != text && '\0' != *text); assert(NULL != pos); std::string fontName = "宋体"; HGUInt fontSize = 10; HGBool bold = HGFALSE; HGBool underline = HGFALSE; HGBool italic = HGFALSE; HGBool strikeout = HGFALSE; if (NULL != fontParam) { fontName = fontParam->foneName; fontSize = fontParam->fontSize; bold = fontParam->bold; underline = fontParam->underline; italic = fontParam->italic; strikeout = fontParam->strikeout; } HGChar moduleName[256]; HGBase_GetModuleName(HGImgProc_AddImageWatermark, moduleName, 256); HGChar modulePath[256]; HGBase_GetFilePath(moduleName, modulePath, 256); HGChar fontPath[256]; sprintf(fontPath, "%s%s.ttf", modulePath, fontName.c_str()); CvxText cvxText; bool ret = cvxText.Create(fontPath); if (ret) { ret = cvxText.MeasureString(text, x, y, fontSize, bold, underline, italic, strikeout, pos); cvxText.Destroy(); } return ret ? HGBASE_ERR_OK : HGBASE_ERR_FAIL; } HGResult HGAPI HGImgProc_AddImageWatermark(HGImage image, const HGChar* text, HGColor color, HGUInt posType, HGInt locationX, HGInt locationY, const HGImgWatermarkFontParam *fontParam) { if (NULL == image || NULL == text || '\0' == *text || posType < HGIMGPROC_WMPOSTYPE_LEFT || posType > HGIMGPROC_WMPOSTYPE_LOCATION) { return HGBASE_ERR_INVALIDARG; } HGImageRoi imgRoi; HGBase_GetImageROI(image, &imgRoi); HGInt roiWidth = imgRoi.right - imgRoi.left; HGInt roiHeight = imgRoi.bottom - imgRoi.top; if (HGIMGPROC_WMPOSTYPE_LOCATION == posType) { std::string fontName = "宋体"; HGUInt fontSize = 10; HGBool bold = HGFALSE; HGBool underline = HGFALSE; HGBool italic = HGFALSE; HGBool strikeout = HGFALSE; if (NULL != fontParam) { fontName = fontParam->foneName; fontSize = fontParam->fontSize; bold = fontParam->bold; underline = fontParam->underline; italic = fontParam->italic; strikeout = fontParam->strikeout; } HGChar moduleName[256]; HGBase_GetModuleName(HGImgProc_AddImageWatermark, moduleName, 256); HGChar modulePath[256]; HGBase_GetFilePath(moduleName, modulePath, 256); HGChar fontPath[256]; sprintf(fontPath, "%s%s.ttf", modulePath, fontName.c_str()); CvxText cvxText; bool ret = cvxText.Create(fontPath); if (ret) { ret = cvxText.DrawString(image, text, locationX, locationY, color, fontSize, bold, underline, italic, strikeout); cvxText.Destroy(); } return ret ? HGBASE_ERR_OK : HGBASE_ERR_FAIL; } HGRect pos; HGResult ret = MeasureString(text, 0, 0, fontParam, &pos); if (HGBASE_ERR_OK != ret) return ret; HGInt stringWidth = pos.right - pos.left; HGInt stringHeight = pos.bottom - pos.top; HGInt x, y; if (HGIMGPROC_WMPOSTYPE_LEFT == posType) { x = 0; y = (roiHeight - stringHeight) / 2; } else if (HGIMGPROC_WMPOSTYPE_TOP == posType) { x = (roiWidth - stringWidth) / 2; y = 0; } else if (HGIMGPROC_WMPOSTYPE_RIGHT == posType) { x = roiWidth - stringWidth; y = (roiHeight - stringHeight) / 2; } else if (HGIMGPROC_WMPOSTYPE_BOTTOM == posType) { x = (roiWidth - stringWidth) / 2; y = roiHeight - stringHeight; } else if (HGIMGPROC_WMPOSTYPE_LEFTTOP == posType) { x = 0; y = 0; } else if (HGIMGPROC_WMPOSTYPE_RIGHTTOP == posType) { x = roiWidth - stringWidth; y = 0; } else if (HGIMGPROC_WMPOSTYPE_LEFTBOTTOM == posType) { x = 0; y = roiHeight - stringHeight; } else if (HGIMGPROC_WMPOSTYPE_RIGHTBOTTOM == posType) { x = roiWidth - stringWidth; y = roiHeight - stringHeight; } else { x = (roiWidth - stringWidth) / 2; y = (roiHeight - stringHeight) / 2; } return HGImgProc_AddImageWatermark(image, text, color, HGIMGPROC_WMPOSTYPE_LOCATION, x, y, fontParam); }