static bool pasteImageToFIBITMAP(const QPoint &pos, FIBITMAP *dst, const T_Image &src) { FREE_IMAGE_TYPE dstType = FreeImage_GetImageType(dst); QSize dstSize(FreeImage_GetWidth(dst), FreeImage_GetHeight(dst)); int dstPitch = FreeImage_GetPitch(dst); uint8_t *dstBits = FreeImage_GetBits(dst); switch (dstType) { case FIT_BITMAP: { int bpp = FreeImage_GetBPP(dst); switch (bpp) { case 24: { auto wrapper = GenericImage<BgrU8>::wrap(dstBits, dstSize, dstPitch); wrapper.paste<ImagePasteDestinationInverted>(src, pos); break; } case 32: { auto wrapper = GenericImage<BgraU8>::wrap(dstBits, dstSize, dstPitch); wrapper.paste<ImagePasteDestinationInverted>(src, pos); break; } default: qWarning() << Q_FUNC_INFO << ": Unsupported data type"; return false; } break; } case FIT_RGB16: { auto wrapper = GenericImage<RgbU16>::wrap(dstBits, dstSize, dstPitch); wrapper.paste<ImagePasteDestinationInverted>(src, pos); break; } case FIT_RGBA16: { auto wrapper = GenericImage<RgbaU16>::wrap(dstBits, dstSize, dstPitch); wrapper.paste<ImagePasteDestinationInverted>(src, pos); break; } default: qWarning() << Q_FUNC_INFO << ": Unsupported data type"; return false; } return true; }
DragImageRef scaleDragImage(DragImageRef image, FloatSize scale) { // FIXME: due to the way drag images are done on windows we need // to preprocess the alpha channel <rdar://problem/5015946> if (!image) return 0; IntSize srcSize = dragImageSize(image); IntSize dstSize(static_cast<int>(srcSize.width() * scale.width()), static_cast<int>(srcSize.height() * scale.height())); HBITMAP hbmp = 0; HDC dc = GetDC(0); HDC dstDC = CreateCompatibleDC(dc); if (!dstDC) goto exit; PlatformContextCairo* targetContext; hbmp = allocImage(dstDC, dstSize, &targetContext); if (!hbmp) goto exit; cairo_surface_t* srcImage = createCairoContextFromBitmap(image); // Scale the target surface to the new image size, and flip it // so that when we set the srcImage as the surface it will draw // right-side-up. cairo_t* cr = targetContext->cr(); cairo_translate(cr, 0, dstSize.height()); cairo_scale(cr, scale.width(), -scale.height()); cairo_set_source_surface(cr, srcImage, 0.0, 0.0); // Now we can paint and get the correct result cairo_paint(cr); cairo_surface_destroy(srcImage); deallocContext(targetContext); ::DeleteObject(image); image = 0; exit: if (!hbmp) hbmp = image; if (dstDC) DeleteDC(dstDC); ReleaseDC(0, dc); return hbmp; }
DragImageRef scaleDragImage(DragImageRef image, FloatSize scale) { // FIXME: due to the way drag images are done on windows we need // to preprocess the alpha channel <rdar://problem/5015946> if (!image) return 0; CGContextRef targetContext; CGContextRef srcContext; CGImageRef srcImage; IntSize srcSize = dragImageSize(image); IntSize dstSize(static_cast<int>(srcSize.width() * scale.width()), static_cast<int>(srcSize.height() * scale.height())); HBITMAP hbmp = 0; HDC dc = GetDC(0); HDC dstDC = CreateCompatibleDC(dc); if (!dstDC) goto exit; hbmp = allocImage(dstDC, dstSize, &targetContext); if (!hbmp) goto exit; srcContext = createCgContextFromBitmap(image); srcImage = CGBitmapContextCreateImage(srcContext); CGRect rect; rect.origin.x = 0; rect.origin.y = 0; rect.size = dstSize; CGContextDrawImage(targetContext, rect, srcImage); CGImageRelease(srcImage); CGContextRelease(srcContext); CGContextRelease(targetContext); ::DeleteObject(image); image = 0; exit: if (!hbmp) hbmp = image; if (dstDC) DeleteDC(dstDC); ReleaseDC(0, dc); return hbmp; }
DragImageRef scaleDragImage(DragImageRef imageRef, FloatSize scale) { // FIXME: due to the way drag images are done on windows we need // to preprocess the alpha channel <rdar://problem/5015946> if (!imageRef) return 0; GDIObject<HBITMAP> hbmp; auto image = adoptGDIObject(imageRef); IntSize srcSize = dragImageSize(image.get()); IntSize dstSize(static_cast<int>(srcSize.width() * scale.width()), static_cast<int>(srcSize.height() * scale.height())); HWndDC dc(0); auto dstDC = adoptGDIObject(::CreateCompatibleDC(dc)); if (!dstDC) goto exit; CGContextRef targetContext; hbmp = allocImage(dstDC.get(), dstSize, &targetContext); if (!hbmp) goto exit; CGContextRef srcContext = createCgContextFromBitmap(image.get()); CGImageRef srcImage = CGBitmapContextCreateImage(srcContext); CGRect rect; rect.origin.x = 0; rect.origin.y = 0; rect.size = dstSize; CGContextDrawImage(targetContext, rect, srcImage); CGImageRelease(srcImage); CGContextRelease(srcContext); CGContextRelease(targetContext); exit: if (!hbmp) hbmp.swap(image); return hbmp.leak(); }
void ImageScalingTransformation::transform(float t, const cv::Mat& source, cv::Mat& result)const { cv::Size dstSize(static_cast<int>(source.cols * t + 0.5f), static_cast<int>(source.rows * t + 0.5f)); cv::resize(source, result, dstSize, cv::INTER_AREA); }
void Face::initMergedFace(const Face &biggerFace, const Face &smallerFace) { // Determine the species of the merged face. if (biggerFace.species == Human && smallerFace.species == Human) { species = Human; } else if (biggerFace.species == Cat && smallerFace.species == Cat) { species = Cat; } else { species = Hybrid; } // Warp the smaller face to align the eyes and nose with the bigger face. cv::Point2f srcPoints[3] = { smallerFace.getLeftEyeCenter(), smallerFace.getRightEyeCenter(), smallerFace.getNoseTip() }; cv::Point2f dstPoints[3] = { biggerFace.leftEyeCenter, biggerFace.rightEyeCenter, biggerFace.noseTip }; cv::Mat affineTransform = cv::getAffineTransform(srcPoints, dstPoints); cv::Size dstSize(biggerFace.mat.cols, biggerFace.mat.rows); cv::warpAffine(smallerFace.mat, mat, affineTransform, dstSize); // Perform any necessary color conversion. // Then, blend the warped face and the original bigger face. switch (mat.channels() - biggerFace.mat.channels()) { case 3: { // The warped face is BGRA and the bigger face is grayscale. cv::Mat otherMat; cv::cvtColor(biggerFace.mat, otherMat, cv::COLOR_GRAY2BGRA); cv::multiply(mat, otherMat, mat, 1.0 / 255.0); break; } case 2: { // The warped face is BGR and the bigger face is grayscale. cv::Mat otherMat; cv::cvtColor(biggerFace.mat, otherMat, cv::COLOR_GRAY2BGR); cv::multiply(mat, otherMat, mat, 1.0 / 255.0); break; } case 1: { // The warped face is BGRA and the bigger face is BGR. cv::Mat otherMat; cv::cvtColor(biggerFace.mat, otherMat, cv::COLOR_BGR2BGRA); cv::multiply(mat, otherMat, mat, 1.0 / 255.0); break; } case -1: // The warped face is BGR and the bigger face is BGRA. cv::cvtColor(mat, mat, cv::COLOR_BGR2BGRA); cv::multiply(mat, biggerFace.mat, mat, 1.0 / 255.0); break; case -2: // The warped face is grayscale and the bigger face is BGR. cv::cvtColor(mat, mat, cv::COLOR_GRAY2BGR); cv::multiply(mat, biggerFace.mat, mat, 1.0 / 255.0); break; case -3: // The warped face is grayscale and the bigger face is BGRA. cv::cvtColor(mat, mat, cv::COLOR_GRAY2BGRA); cv::multiply(mat, biggerFace.mat, mat, 1.0 / 255.0); break; default: // The color formats are the same. cv::multiply(mat, biggerFace.mat, mat, 1.0 / 255.0); break; } // The points of interest match the original bigger face. leftEyeCenter = biggerFace.leftEyeCenter; rightEyeCenter = biggerFace.rightEyeCenter; noseTip = biggerFace.noseTip; }
gl::Error Framebuffer9::blitImpl(const gl::Rectangle &sourceArea, const gl::Rectangle &destArea, const gl::Rectangle *scissor, bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter, const gl::Framebuffer *sourceFramebuffer) { ASSERT(filter == GL_NEAREST); IDirect3DDevice9 *device = mRenderer->getDevice(); ASSERT(device); mRenderer->endScene(); if (blitRenderTarget) { const gl::FramebufferAttachment *readBuffer = sourceFramebuffer->getColorbuffer(0); ASSERT(readBuffer); RenderTarget9 *readRenderTarget = nullptr; gl::Error error = readBuffer->getRenderTarget(&readRenderTarget); if (error.isError()) { return error; } ASSERT(readRenderTarget); const gl::FramebufferAttachment *drawBuffer = mState.getColorAttachment(0); ASSERT(drawBuffer); RenderTarget9 *drawRenderTarget = nullptr; error = drawBuffer->getRenderTarget(&drawRenderTarget); if (error.isError()) { return error; } ASSERT(drawRenderTarget); // The getSurface calls do an AddRef so save them until after no errors are possible IDirect3DSurface9* readSurface = readRenderTarget->getSurface(); ASSERT(readSurface); IDirect3DSurface9* drawSurface = drawRenderTarget->getSurface(); ASSERT(drawSurface); gl::Extents srcSize(readRenderTarget->getWidth(), readRenderTarget->getHeight(), 1); gl::Extents dstSize(drawRenderTarget->getWidth(), drawRenderTarget->getHeight(), 1); RECT srcRect; srcRect.left = sourceArea.x; srcRect.right = sourceArea.x + sourceArea.width; srcRect.top = sourceArea.y; srcRect.bottom = sourceArea.y + sourceArea.height; RECT dstRect; dstRect.left = destArea.x; dstRect.right = destArea.x + destArea.width; dstRect.top = destArea.y; dstRect.bottom = destArea.y + destArea.height; // Clip the rectangles to the scissor rectangle if (scissor) { if (dstRect.left < scissor->x) { srcRect.left += (scissor->x - dstRect.left); dstRect.left = scissor->x; } if (dstRect.top < scissor->y) { srcRect.top += (scissor->y - dstRect.top); dstRect.top = scissor->y; } if (dstRect.right > scissor->x + scissor->width) { srcRect.right -= (dstRect.right - (scissor->x + scissor->width)); dstRect.right = scissor->x + scissor->width; } if (dstRect.bottom > scissor->y + scissor->height) { srcRect.bottom -= (dstRect.bottom - (scissor->y + scissor->height)); dstRect.bottom = scissor->y + scissor->height; } } // Clip the rectangles to the destination size if (dstRect.left < 0) { srcRect.left += -dstRect.left; dstRect.left = 0; } if (dstRect.right > dstSize.width) { srcRect.right -= (dstRect.right - dstSize.width); dstRect.right = dstSize.width; } if (dstRect.top < 0) { srcRect.top += -dstRect.top; dstRect.top = 0; } if (dstRect.bottom > dstSize.height) { srcRect.bottom -= (dstRect.bottom - dstSize.height); dstRect.bottom = dstSize.height; } // Clip the rectangles to the source size if (srcRect.left < 0) { dstRect.left += -srcRect.left; srcRect.left = 0; } if (srcRect.right > srcSize.width) { dstRect.right -= (srcRect.right - srcSize.width); srcRect.right = srcSize.width; } if (srcRect.top < 0) { dstRect.top += -srcRect.top; srcRect.top = 0; } if (srcRect.bottom > srcSize.height) { dstRect.bottom -= (srcRect.bottom - srcSize.height); srcRect.bottom = srcSize.height; } HRESULT result = device->StretchRect(readSurface, &srcRect, drawSurface, &dstRect, D3DTEXF_NONE); SafeRelease(readSurface); SafeRelease(drawSurface); if (FAILED(result)) { return gl::Error(GL_OUT_OF_MEMORY, "Internal blit failed, StretchRect returned 0x%X.", result); } } if (blitDepth || blitStencil) { const gl::FramebufferAttachment *readBuffer = sourceFramebuffer->getDepthOrStencilbuffer(); ASSERT(readBuffer); RenderTarget9 *readDepthStencil = nullptr; gl::Error error = readBuffer->getRenderTarget(&readDepthStencil); if (error.isError()) { return error; } ASSERT(readDepthStencil); const gl::FramebufferAttachment *drawBuffer = mState.getDepthOrStencilAttachment(); ASSERT(drawBuffer); RenderTarget9 *drawDepthStencil = nullptr; error = drawBuffer->getRenderTarget(&drawDepthStencil); if (error.isError()) { return error; } ASSERT(drawDepthStencil); // The getSurface calls do an AddRef so save them until after no errors are possible IDirect3DSurface9* readSurface = readDepthStencil->getSurface(); ASSERT(readDepthStencil); IDirect3DSurface9* drawSurface = drawDepthStencil->getSurface(); ASSERT(drawDepthStencil); HRESULT result = device->StretchRect(readSurface, nullptr, drawSurface, nullptr, D3DTEXF_NONE); SafeRelease(readSurface); SafeRelease(drawSurface); if (FAILED(result)) { return gl::Error(GL_OUT_OF_MEMORY, "Internal blit failed, StretchRect returned 0x%X.", result); } } return gl::Error(GL_NO_ERROR); }