QImage ImageCache::image(QString path, int width, int height, int &origWidth, int &origHeight) { if (m_cacheDir.isEmpty()) return scaledImage(Helper::instance()->getImage(path), width, height); QString md5 = QCryptographicHash::hash(path.toUtf8(), QCryptographicHash::Md5).toHex(); QString baseName = QString("%1_%2_%3_").arg(md5).arg(width).arg(height); bool update = true; QDir dir(m_cacheDir); QStringList files = dir.entryList(QStringList() << baseName + "*"); if (!files.isEmpty()) { QString fileName = files.first(); QStringList parts = fileName.split("_"); if (parts.count() > 6) { origWidth = parts.at(3).toInt(); origHeight = parts.at(4).toInt(); if (m_forceCache || parts.at(5).toInt() == getLastModified(path)) update = false; } } if (update) { QImage origImg = Helper::instance()->getImage(path); origWidth = origImg.width(); origHeight = origImg.height(); QImage img = scaledImage(origImg, width, height); img.save(m_cacheDir + "/" + QString("%1_%2_%3_%4_%5_%6_.png").arg(md5).arg(width).arg(height).arg(origWidth).arg(origHeight).arg(getLastModified(path)), "png", -1); return img; } return Helper::instance()->getImage(m_cacheDir + "/" + files.first()); }
cv::Mat3b OpenCVUtil::tile_image_patches(const std::vector<cv::Mat3b>& images, int tileCols, int tileRows, int patchWidth, int patchHeight, int paddingSize) { // Scale and pad the input images to make the tiles. std::vector<cv::Mat3b> tiles; for(size_t i = 0, size = images.size(); i < size; ++i) { cv::Mat3b scaledImage(patchHeight, patchWidth); cv::resize(images[i], scaledImage, scaledImage.size(), 0.0, 0.0, CV_INTER_NN); tiles.push_back(pad_image(scaledImage, paddingSize)); } // Make a blank output image of the right size to which the tiles can be copied. const int tileHeight = patchHeight + 2 * paddingSize; const int tileWidth = patchWidth + 2 * paddingSize; cv::Mat3b tiledImage = cv::Mat3b::zeros(tileHeight * tileRows, tileWidth * tileCols); // Copy the tiles across to the output image. for(int i = 0, tileCount = tileCols * tileRows; i < tileCount; ++i) { int x = (i % tileCols) * tileWidth; int y = (i / tileCols) * tileHeight; cv::Rect roi(x, y, tileWidth, tileHeight); tiles[i].copyTo(tiledImage(roi)); } return tiledImage; }
void Texture::GenerateManualMipmaps(const Image& image) const { unsigned int closestXPowerOf2 = Texture::ClosestPowerOf2(image.Width()); unsigned int closestYPowerOf2 = Texture::ClosestPowerOf2(image.Height()); Image scaledImage(image); if ((closestXPowerOf2 != image.Width()) || (closestYPowerOf2 != image.Height())) { scaledImage.Scale(closestXPowerOf2, closestYPowerOf2); } GenerateManualMipmapsUsingPowerOf2Image(scaledImage); }
int DrawSdk::Image::WriteScaledImageFile(WCHAR* scaledImageName, float scaleX, float scaleY, const WCHAR* format) { int hr = S_OK; // // Starting the Gdiplus machine should be executed outside of this method // Gdiplus::GdiplusStartupInput gdiplusStartupInput; // ULONG_PTR gdiplusToken; // Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); Gdiplus::ImageCodecInfo *pImageCodecInfo = NULL; CLSID *pClsid = NULL; HDC hdc = CreateCompatibleDC(NULL); // Get the encoder CLSID depending on the image format (image/jpeg, image/gif, image/png) UINT num = 0; UINT size = 0; Gdiplus::GetImageEncodersSize(&num, &size); if (size == 0) hr = -1; // Failure if (SUCCEEDED(hr)) { pImageCodecInfo = (Gdiplus::ImageCodecInfo*)(malloc(size)); if (pImageCodecInfo == NULL) hr = -1; // Failure } if (SUCCEEDED(hr)) { Gdiplus::GetImageEncoders(num, size, pImageCodecInfo); for(int j = 0; j < num; ++j) { if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 ) { pClsid = &pImageCodecInfo[j].Clsid; break; // Success } } if (pClsid == NULL) hr = -1; // Failure } // Bugfix 5301: // If 'gdipImage_' is NULL then it was not kept in memory and therefore // a temporary Gdiplus::Image object is created for the rescaling. // This avoids having too much image data in the memory. Gdiplus::Image *tmpImage = NULL; if (SUCCEEDED(hr) && gdipImage_ == NULL) { // convert char-String in WCHAR-String int iStringLength = _tcslen(imageName_) + 1; WCHAR *wcFilename = (WCHAR *)malloc(iStringLength*sizeof(WCHAR)); #ifdef _UNICODE wcscpy(wcFilename, imageName_); #else MultiByteToWideChar( CP_ACP, 0, imageName, iStringLength, wcFilename, iStringLength); #endif tmpImage = new Gdiplus::Image(wcFilename, FALSE); if (wcFilename) free(wcFilename); } else { tmpImage = gdipImage_; } if (SUCCEEDED(hr) && tmpImage != NULL) { // Resize the image by scaling factors Gdiplus::REAL destWidth = scaleX * this->GetWidth(); Gdiplus::REAL destHeight = scaleY * this->GetHeight(); // If no correct size is defined in the object queue, use the real image size instead if ( (this->GetWidth() <= 0.0f) && (this->GetHeight() <= 0.0f) ) { destWidth = scaleX * tmpImage->GetWidth(); destHeight = scaleY * tmpImage->GetHeight(); } // At least we have to write one pixel if (destWidth < 1.0f) destWidth = 1.0f; if (destHeight < 1.0f) destHeight = 1.0f; Gdiplus::Bitmap scaledImage((int)(destWidth + 0.5f), (int)(destHeight + 0.5f)); scaledImage.SetResolution(tmpImage->GetHorizontalResolution(), tmpImage->GetVerticalResolution()); Gdiplus::Graphics grPhoto(&scaledImage); grPhoto.SetCompositingQuality(Gdiplus::CompositingQualityHighSpeed); grPhoto.SetCompositingMode(Gdiplus::CompositingModeSourceOver); grPhoto.SetInterpolationMode(Gdiplus::InterpolationModeHighQualityBicubic); Gdiplus::Rect destRect(0, 0, (int)(destWidth + 0.5f), (int)(destHeight + 0.5f)); hr = grPhoto.DrawImage(tmpImage, destRect, 0, 0, tmpImage->GetWidth(),tmpImage->GetHeight(), Gdiplus::UnitPixel); // Write the scaled image to a file if (SUCCEEDED(hr)) hr = scaledImage.Save(scaledImageName, pClsid, NULL); } // Cleanup if (hdc) { ::DeleteDC(hdc); hdc = NULL; } if (pImageCodecInfo) { free(pImageCodecInfo); pImageCodecInfo = NULL; } if (tmpImage != NULL && tmpImage != gdipImage_) delete tmpImage; // // Stop the Gdiplus machine --> this should be executed outside of this method (see above) // Gdiplus::GdiplusShutdown(gdiplusToken); return hr; }
void CascadeClassifier::detectMultiScaleNoGrouping( const Mat& image, std::vector<Rect>& candidates, std::vector<int>& rejectLevels, std::vector<double>& levelWeights, double scaleFactor, Size minObjectSize, Size maxObjectSize, bool outputRejectLevels ) { candidates.clear(); if (!maskGenerator.empty()) maskGenerator->initializeMask(image); if( maxObjectSize.height == 0 || maxObjectSize.width == 0 ) maxObjectSize = image.size(); Mat grayImage = image; if( grayImage.channels() > 1 ) { Mat temp; cvtColor(grayImage, temp, COLOR_BGR2GRAY); grayImage = temp; } Mat imageBuffer(image.rows + 1, image.cols + 1, CV_8U); for( double factor = 1; ; factor *= scaleFactor ) { Size originalWindowSize = getOriginalWindowSize(); Size windowSize( cvRound(originalWindowSize.width*factor), cvRound(originalWindowSize.height*factor) ); Size scaledImageSize( cvRound( grayImage.cols/factor ), cvRound( grayImage.rows/factor ) ); Size processingRectSize( scaledImageSize.width - originalWindowSize.width, scaledImageSize.height - originalWindowSize.height ); if( processingRectSize.width <= 0 || processingRectSize.height <= 0 ) break; if( windowSize.width > maxObjectSize.width || windowSize.height > maxObjectSize.height ) break; if( windowSize.width < minObjectSize.width || windowSize.height < minObjectSize.height ) continue; Mat scaledImage( scaledImageSize, CV_8U, imageBuffer.data ); resize( grayImage, scaledImage, scaledImageSize, 0, 0, INTER_LINEAR ); int yStep; if( getFeatureType() == cv::FeatureEvaluator::HOG ) { yStep = 4; } else { yStep = factor > 2. ? 1 : 2; } int stripCount, stripSize; const int PTS_PER_THREAD = 1000; stripCount = ((processingRectSize.width/yStep)*(processingRectSize.height + yStep-1)/yStep + PTS_PER_THREAD/2)/PTS_PER_THREAD; stripCount = std::min(std::max(stripCount, 1), 100); stripSize = (((processingRectSize.height + stripCount - 1)/stripCount + yStep-1)/yStep)*yStep; if( !detectSingleScale( scaledImage, stripCount, processingRectSize, stripSize, yStep, factor, candidates, rejectLevels, levelWeights, outputRejectLevels ) ) break; } }