void DlgDataExt::UpdatePreview() { if (m_image){ CxImage tmp; tmp.Copy(*m_image,true,false,false); if (m_chk_preview.GetCheck()){ UpdateData(1); if (m_btn_graylevel.GetCheck()){ tmp.Threshold(m_thresh); } else { tmp.SelectionAddColor(tmp.RGBtoRGBQUAD(m_color)); tmp.SelectionSplit(&tmp); tmp.Negative(); } } tmp.IncreaseBpp(24); tmp.Resample(150,90,0); if (m_bitmap) DeleteObject(m_bitmap); m_bitmap = tmp.MakeBitmap(m_picture.GetDC()->m_hDC); m_picture.SetBitmap(m_bitmap); } }
bool CPicShowCtrl::SaveFile(CString strPath) { int width=180; int height=180; CPaintDC dc(this); CxImage img; img.CreateFromHBITMAP(m_hBmp); CBitmap bitmapmem; CBitmap *pOldBit; CDC m_pMemDC; m_pMemDC.CreateCompatibleDC(&dc); bitmapmem.CreateCompatibleBitmap(&dc, width, height); pOldBit=m_pMemDC.SelectObject(&bitmapmem); CRect rect(0,0,width,height); HBRUSH bgBrush = ::CreateSolidBrush(RGB(255,255,255)); FillRect(m_pMemDC,&rect,bgBrush); DeleteObject(bgBrush); img.Draw(m_pMemDC,m_iStartx,m_iStarty,img.GetWidth(),img.GetHeight(),&rect); CBitmap* pBmp=m_pMemDC.SelectObject(pOldBit); CxImage xImagebmp; xImagebmp.CreateFromHBITMAP((HBITMAP)bitmapmem.m_hObject); xImagebmp.Resample(100,100,0); bitmapmem.DeleteObject(); m_pMemDC.DeleteDC(); if(xImagebmp.Save(common::utility::stringhelper::UnicodeToAscii(strPath.GetBuffer()).c_str(), CXIMAGE_FORMAT_JPG)) { return true; } return false; }
int ResampleKeepAspect(CxImage &image, unsigned int width, unsigned int height) { bool bResize = false; float fAspect = ((float)image.GetWidth()) / ((float)image.GetHeight()); unsigned int newwidth = image.GetWidth(); unsigned int newheight = image.GetHeight(); if (newwidth > width) { bResize = true; newwidth = width; newheight = (DWORD)( ( (float)newwidth) / fAspect); } if (newheight > height) { bResize = true; newheight = height; newwidth = (DWORD)( fAspect * ( (float)newheight) ); } if (bResize) { if (!image.Resample(newwidth, newheight, RESAMPLE_QUALITY) || !image.IsValid()) { printf("PICTURE::SaveThumb: Unable to resample picture: Error:%s\n", image.GetLastError()); return -1; } } return bResize ? 1 : 0; }
STDMETHODIMP CContextMenu::MenuMessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *plResult) { TRACE("CContextMenu::MenuMessageHandler()"); CRASH_PROTECT_START; switch (uMsg) { case WM_MEASUREITEM: { LPMEASUREITEMSTRUCT itemInfo = (LPMEASUREITEMSTRUCT)lParam; MatroskaAttachmentMenuItem *currentAttachmentStruct = (MatroskaAttachmentMenuItem *)itemInfo->itemData; MatroskaAttachmentItem *currentAttachment = currentAttachmentStruct->attachmentSource; if (currentAttachment != NULL) { // An image attachment CxImage *attachedImage = currentAttachment->GetCxImage(); if (attachedImage != NULL) { //TCHAR track_txt[256]; //_sntprintf(track_txt, 255, _T("%i x %i, %i bits"), attachedImage->GetWidth(), attachedImage->GetHeight(), attachedImage->GetBpp()); ModifyMenuA(currentAttachmentStruct->hmAttachmentItem, currentAttachmentStruct->uIDNewItem, MF_STRING|MF_BYCOMMAND, currentAttachmentStruct->uIDNewItem, currentAttachment->GetImageInfo().c_str()); SIZE correctSize = SmartResize(attachedImage->GetWidth(), attachedImage->GetHeight(), 100, 100); attachedImage->Resample(correctSize.cx, correctSize.cy, MatroskaShellExt_GetRegistryValue(_T("ThumbnailResizeMethod"), 0)); itemInfo->itemWidth = correctSize.cx; itemInfo->itemHeight = correctSize.cy; } } break; } case WM_DRAWITEM: { LPDRAWITEMSTRUCT itemInfo = (LPDRAWITEMSTRUCT)lParam; MatroskaAttachmentMenuItem *currentAttachmentStruct = (MatroskaAttachmentMenuItem *)itemInfo->itemData; MatroskaAttachmentItem *currentAttachment = currentAttachmentStruct->attachmentSource; if (currentAttachment != NULL) { // An image attachment CxImage *attachedImage = currentAttachment->GetCxImage(); if (attachedImage != NULL) { long leftPos = (itemInfo->rcItem.right - itemInfo->rcItem.left - attachedImage->GetWidth()) / 2 + itemInfo->rcItem.left; long topPos = itemInfo->rcItem.top; attachedImage->Draw(itemInfo->hDC, leftPos, topPos); } } break; } } CRASH_PROTECT_END; return S_OK; };
// This must be called before any frame-saving is attempted. void CAnimationExporter::CreateGif() { if(!g_canvas || !g_canvas->model || !g_canvas->model->animManager) { wxMessageBox(_T("Unable to create animated GIF!"), _T("Error") ); wxLogMessage(_T( "Error: Unable to created animated GIF. A required objects pointer was null!") ); Show(false); return ; } CxImage **gifImages = NULL; // Our pointer array of images // Reset the state of our GUI objects btnStart->Enable(false); btnCancel->Enable(false); cbGrey->Enable(false); cbTrans->Enable(false); cbDither->Enable(false); cbShrink->Enable(false); txtFrames->Enable(false); txtSizeX->Enable(false); txtSizeY->Enable(false); txtDelay->Enable(false); // Pause our rendering to screen so we can focus on making the animated image g_videoSetting.render = false; m_fAnimSpeed = g_canvas->model->animManager->GetSpeed(); // Save the old animation speed g_canvas->model->animManager->SetSpeed(1.0f); // Set it to the normal speed. m_iTotalAnimFrames = g_canvas->model->animManager->GetFrameCount(); wxString(txtFrames->GetValue() ).ToLong( (long*) &m_iTotalFrames); wxString(txtDelay->GetValue() ).ToLong( (long*) &m_iDelay); // will crash program - prevent this from happening if(m_iTotalFrames > m_iTotalAnimFrames) { wxMessageBox(_T( "Impossible to make a gif with more frames than the model animation.\nClosing gif exporter."), _T("Error") ); wxLogMessage(_T( "Error: Unable to make a gif with more frames than the model animation.") ); this->Show(false); return ; } if(m_iDelay < 1) { m_iDelay = 1; } if(m_iDelay > 100) { m_iDelay = 100; } m_iTimeStep = int(m_iTotalAnimFrames / m_iTotalFrames); // Total number of frames in the animation / total frames going into our exported animation image if(m_bShrink) { wxString(txtSizeX->GetValue() ).ToLong( (long*) &m_iNewWidth); wxString(txtSizeY->GetValue() ).ToLong( (long*) &m_iNewHeight); // Just a minor check, final image size can not be smaller than 32x32 pixels. if(m_iNewWidth < 32 || m_iNewHeight < 32) { m_iNewWidth = 32; m_iNewHeight = 32; } } // CREATE OUR RENDERTOTEXTURE OBJECT // ------------------------------------------- // if either are supported use our 'RenderTexture' object. if(g_videoSetting.supportPBO || g_videoSetting.supportVBO) { g_canvas->rt = new RenderTexture(); if(!g_canvas->rt) { wxLogMessage(_T("Error: RenderToTexture object is null!") ); this->Show(false); return ; } g_canvas->rt->Init( (HWND)g_canvas->GetHandle(), 0, 0, g_videoSetting.supportFBO) ; m_iWidth = g_canvas->rt->nWidth; m_iHeight = g_canvas->rt->nHeight; g_canvas->rt->BeginRender(); } else { glReadBuffer(GL_BACK); int screenSize[4]; glGetIntegerv(GL_VIEWPORT, screenSize); // get the width/height of the canvas m_iWidth = screenSize[2]; m_iHeight = screenSize[3]; return ; } // Stop our animation g_canvas->model->animManager->Pause(true); g_canvas->model->animManager->Stop(); g_canvas->model->animManager->AnimateParticles(); // Size of our buffer to hold the pixel data m_iSize = m_iWidth * m_iHeight * 4; // (width*height*bytesPerPixel) // Create one frame to make our optimal colour palette from. unsigned char *buffer = new unsigned char[m_iSize]; gifImages = new CxImage *[m_iTotalFrames]; for(unsigned int i = 0; i < m_iTotalFrames; i++) { lblCurFrame->SetLabel(wxString::Format(_T("Current Frame: %i"), i) ); this->Refresh(); this->Update(); CxImage *newImage = new CxImage(0); g_canvas->RenderToBuffer(); glReadPixels(0, 0, m_iWidth, m_iHeight, GL_BGRA_EXT, GL_UNSIGNED_BYTE, buffer); newImage->CreateFromArray(buffer, m_iWidth, m_iHeight, 32, (m_iWidth *4) , false); // not needed due to the code just below, which fixes the issue with particles //g_canvas->model->animManager->SetTimeDiff(m_iTimeStep); //g_canvas->model->animManager->Tick(m_iTimeStep); if(g_canvas->root) { g_canvas->root->tick( (float)m_iTimeStep); } if(g_canvas->sky) { g_canvas->sky->tick( (float)m_iTimeStep); } #ifdef _WIN32 if(m_bGreyscale) { newImage->GrayScale(); } #endif //_WIN32 if(m_bShrink && m_iNewWidth != m_iWidth && m_iNewHeight != m_iHeight) { newImage->Resample(m_iNewWidth, m_iNewHeight, 2); } // if (Optimise) { if(!m_pPal) { CQuantizer q(256, 8); q.ProcessImage( (HANDLE)newImage->GetDIB() ); m_pPal = (RGBQUAD*)calloc(256 *sizeof(RGBQUAD), 1); //This creates our gifs optimised global colour palette q.SetColorTable(m_pPal); } newImage->DecreaseBpp(8, m_bDiffuse, m_pPal, 256); newImage->SetCodecOption(2); // for LZW compression if(m_bTransparent) { newImage->SetTransIndex(newImage->GetPixelIndex(0, 0) ); } newImage->SetFrameDelay(m_iDelay); gifImages[i] = newImage; // All the memory that we allocate for newImage gets cleared at the end } wxDELETEA(buffer); if(g_videoSetting.supportPBO || g_videoSetting.supportVBO) { g_canvas->rt->EndRender(); // Clear RenderTexture object. g_canvas->rt->Shutdown(); wxDELETE(g_canvas->rt); } // CREATE THE ACTUAL MULTI-IMAGE GIF ANIMATION // ------------------------------------------------------ // Create the file and write all the data // Open/Create the file that were going to save to FILE *hFile = NULL; hFile = fopen(m_strFilename.fn_str(), "wb"); // Set gif options CxImageGIF multiImage; multiImage.SetComment("Exported from WoW Model Viewer"); if(m_bTransparent) { multiImage.SetDisposalMethod(2); } else { multiImage.SetDisposalMethod(0); } multiImage.SetFrameDelay(m_iDelay); multiImage.SetCodecOption(2); // LZW multiImage.SetLoops(0); // Set the animation to loop indefinately. // Create/Compose the animated gif multiImage.Encode(hFile, gifImages, m_iTotalFrames, false); // ALL DONE, START THE CLEAN UP // -------------------------------------------------------- // Close file fclose(hFile); // Free the memory used by all the images to create the GIF for(unsigned int i = 0; i < m_iTotalFrames; i++) { gifImages[i]->Destroy(); wxDELETE(gifImages[i]); } wxDELETEA(gifImages); // Free memory used by the colour palette if(m_pPal) { free(m_pPal); m_pPal = NULL; } wxLogMessage(_T("Info: GIF Animation successfully created.") ); g_canvas->model->animManager->SetSpeed(m_fAnimSpeed); // Return the animation speed back to whatever it was previously set as g_canvas->model->animManager->Play(); Show(false); g_videoSetting.render = true; g_canvas->InitView(); }
UINT CFrameGrabThread::GrabFrames(){ #define TIMEBETWEENFRAMES 50.0 // could be a param later, if needed for (int i = 0; i!= nFramesToGrab; i++) imgResults[i] = NULL; try{ HRESULT hr; CComPtr<IMediaDet> pDet; hr = pDet.CoCreateInstance(__uuidof(MediaDet)); if (!SUCCEEDED(hr)) return 0; // Convert the file name to a BSTR. CComBSTR bstrFilename(strFileName); hr = pDet->put_Filename(bstrFilename); long lStreams; bool bFound = false; hr = pDet->get_OutputStreams(&lStreams); for (long i = 0; i < lStreams; i++) { GUID major_type; hr = pDet->put_CurrentStream(i); hr = pDet->get_StreamType(&major_type); if (major_type == MEDIATYPE_Video) { bFound = true; break; } } if (!bFound) return 0; double dLength = 0; pDet->get_StreamLength(&dLength); if (dStartTime > dLength) dStartTime = 0; long width = 0, height = 0; AM_MEDIA_TYPE mt; hr = pDet->get_StreamMediaType(&mt); if (mt.formattype == FORMAT_VideoInfo) { VIDEOINFOHEADER *pVih = (VIDEOINFOHEADER*)(mt.pbFormat); width = pVih->bmiHeader.biWidth; height = pVih->bmiHeader.biHeight; // We want the absolute height, don't care about orientation. if (height < 0) height *= -1; } else { return 0; // Should not happen, in theory. } /*FreeMediaType(mt); = */ if (mt.cbFormat != 0){ CoTaskMemFree((PVOID)mt.pbFormat); mt.cbFormat = 0; mt.pbFormat = NULL; } if (mt.pUnk != NULL){ mt.pUnk->Release(); mt.pUnk = NULL; } /**/ long size; uint32 nFramesGrabbed; for (nFramesGrabbed = 0; nFramesGrabbed != nFramesToGrab; nFramesGrabbed++){ hr = pDet->GetBitmapBits(dStartTime + (nFramesGrabbed*TIMEBETWEENFRAMES), &size, NULL, width, height); if (SUCCEEDED(hr)) { // we could also directly create a Bitmap in memory, however this caused problems/failed with *some* movie files // when I tried it for the MMPreview, while this method works always - so I'll continue to use this one long nFullBufferLen = sizeof( BITMAPFILEHEADER ) + size; char* buffer = new char[nFullBufferLen]; BITMAPFILEHEADER bfh; memset( &bfh, 0, sizeof( bfh ) ); bfh.bfType = 'MB'; bfh.bfSize = nFullBufferLen; bfh.bfOffBits = sizeof( BITMAPINFOHEADER ) + sizeof( BITMAPFILEHEADER ); memcpy(buffer,&bfh,sizeof( bfh ) ); try { hr = pDet->GetBitmapBits(dStartTime+ (nFramesGrabbed*TIMEBETWEENFRAMES), NULL, buffer + sizeof( bfh ), width, height); } catch (...) { ASSERT(0); hr = E_FAIL; } if (SUCCEEDED(hr)) { // decode CxImage* imgResult = new CxImage(); imgResult->Decode((BYTE*)buffer, nFullBufferLen, CXIMAGE_FORMAT_BMP); delete[] buffer; if (!imgResult->IsValid()){ delete imgResult; break; } // resize if needed if (nMaxWidth > 0 && nMaxWidth < width){ float scale = (float)nMaxWidth / imgResult->GetWidth(); int nMaxHeigth = (int)(imgResult->GetHeight() * scale); imgResult->Resample(nMaxWidth, nMaxHeigth, 0); } // decrease bpp if needed if (bReduceColor){ RGBQUAD* ppal=(RGBQUAD*)malloc(256*sizeof(RGBQUAD)); if (ppal) { CQuantizer q(256,8); q.ProcessImage(imgResult->GetDIB()); q.SetColorTable(ppal); imgResult->DecreaseBpp(8, true, ppal); free(ppal); } } //CString TestName; //TestName.Format("G:\\testframe%i.png",nFramesGrabbed); //imgResult->Save(TestName,CXIMAGE_FORMAT_PNG); // done imgResults[nFramesGrabbed] = imgResult; } else{ delete[] buffer; break; } } } return nFramesGrabbed; } catch(...){ ASSERT(0); return 0; } }
void CCxImageARDlg::OnBnClickedBtnTemplate() { // TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다. if(cxImageARDoc.GetImage() != NULL){ CxImage* cropImage = new CxImage; CxImage* templateImage = new CxImage; CxImage* buffer = cxImageARDoc.Binarization(original); TCHAR* templatePath[4]; templatePath[0] = _T("..\\template\\template01.bmp"); templatePath[1] = _T("..\\template\\template02.bmp"); templatePath[2] = _T("..\\template\\template03.bmp"); templatePath[3] = _T("..\\template\\template04.bmp"); int width = original->GetWidth(); int height = original->GetHeight(); bool findmarker = false; const int search_window = 243; for(int k = 0; k < 1; k++){ for(int y = 1; y < height-search_window; y+=4){ for(int x = 1; x < width-search_window; x+=4){ /* load template Image */ templateImage->Load(templatePath[k], cxImageARDoc.FindType(templatePath[k])); templateImage = cxImageARDoc.Binarization(templateImage); /* extract the region of search window */ cropImage = cxImageARDoc.extractRegion(CPointInt(x, y), CPointInt(x+search_window, y+search_window), buffer); /* Draw template and search window */ CDC* pDC1, *pDC2; CRect rect1, rect2; pDC1 = m_pic_search.GetDC(); m_pic_search.GetClientRect(&rect1); cropImage->Draw(pDC1->m_hDC, rect1); pDC2 = m_pic_template.GetDC(); m_pic_template.GetClientRect(&rect2); templateImage->Draw(pDC2->m_hDC, rect2); ReleaseDC(pDC1); ReleaseDC(pDC2); /* template matching processing */ cropImage->Resample(64, 64); if(cxImageARDoc.templateMatching(templateImage, cropImage)){ /* if template matching is true, then draw the rect of matched area */ RGBQUAD color; color.rgbBlue = 0; color.rgbGreen = 255; color.rgbRed = 0; cxImageARDoc.drawRect(CPointInt(x, y), CPointInt(x+search_window, y+search_window), result, color); findmarker = true; break; } } if(findmarker) break; } if(findmarker) break; } delete buffer; delete cropImage; delete templateImage; } }