void CCaptchaGenerator::ReGenerateCaptcha(uint32 nLetterCount) { Clear(); CxImage* pimgResult = new CxImage(nLetterCount > 1 ? (LETTERSIZE + (nLetterCount-1)*CROWDEDSIZE) : LETTERSIZE, 32, 1, CXIMAGE_FORMAT_BMP); pimgResult->SetPaletteColor(0, 255, 255, 255); pimgResult->SetPaletteColor(1, 0, 0, 0, 0); pimgResult->Clear(); CxImage imgBlank(LETTERSIZE, LETTERSIZE, 1, CXIMAGE_FORMAT_BMP); imgBlank.SetPaletteColor(0, 255, 255, 255); imgBlank.SetPaletteColor(1, 0, 0, 0, 0); imgBlank.Clear(); for (uint32 i = 0; i < nLetterCount; i++) { CxImage imgLetter(imgBlank); CString strLetter(schCaptchaContent[GetRandomUInt16() % ARRSIZE(schCaptchaContent)]); m_strCaptchaText += strLetter; uint16 nRandomSize = GetRandomUInt16() % 10; uint16 nRandomOffset = 3 + GetRandomUInt16() % 11; imgLetter.DrawString(NULL, nRandomOffset, 32, strLetter, imgLetter.RGBtoRGBQUAD(RGB(0, 0, 0)), _T("Arial"), 40 - nRandomSize, 1000); //imgLetter.DrawTextA(NULL, nRandomOffset, 32, strLetter, imgLetter.RGBtoRGBQUAD(RGB(0, 0, 0)), "Arial", 40 - nRandomSize, 1000); float fRotate = (float)(35 - (GetRandomUInt16() % 70)); imgLetter.Rotate2(fRotate, NULL, CxImage::IM_BILINEAR, CxImage::OM_BACKGROUND, 0, false, true); uint32 nOffset = i * CROWDEDSIZE; ASSERT( imgLetter.GetHeight() == pimgResult->GetHeight() && pimgResult->GetWidth() >= nOffset + imgLetter.GetWidth() ); for (uint32 j = 0; j < imgLetter.GetHeight(); j++) for (uint32 k = 0; k < imgLetter.GetWidth(); k++) if (pimgResult->GetPixelIndex(nOffset + k, j) != 1) pimgResult->SetPixelIndex(nOffset + k, j, imgLetter.GetPixelIndex(k, j)); } pimgResult->Jitter(1); //pimgResult->Save("D:\\CaptchaTest.bmp", CXIMAGE_FORMAT_BMP); m_pimgCaptcha = pimgResult; }
// 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(); }
void CDemoView::OnLButtonDown(UINT nFlags, CPoint point) { CDemoDoc* pDoc = GetDocument(); if (pDoc) { switch(pDoc->m_tool){ case 0: // select case 1: { #ifdef VATI_EXTENSIONS if ( nFlags & MK_SHIFT ) pDoc->m_isRectSel = 1; else pDoc->m_isRectSel = 0; #endif CxImage* ima = pDoc->GetImage(); if (ima) { m_RefScroll = GetScrollPosition(); m_RefPoint.x = point.x; m_RefPoint.y = point.y; } } break; case 2: // zoom if (!pDoc->GetWaitingClick()) PostMessage(WM_COMMAND,ID_VIEW_ZOOMIN); break; case 4: // tracker { if (m_tracker.HitTest(point) < 0) { CRectTracker track; if (track.TrackRubberBand(this, point, true)) { track.m_rect.NormalizeRect(); m_tracker.m_rect = track.m_rect; SetImageRectSelection(pDoc,&(m_tracker.m_rect)); } else { m_tracker.m_rect = CRect(0,0,0,0); } } else { if (m_tracker.Track(this, point, true)){ m_tracker.m_rect.NormalizeRect(); SetImageRectSelection(pDoc,&(m_tracker.m_rect)); } else { m_tracker.m_rect = CRect(0,0,0,0); } } OnUpdate(0,0,0); } break; case 3: //text { //pDoc->m_tool=-1; CxImage* ima = pDoc->GetImage(); if (ima){ pDoc->SubmitUndo(); long x = point.x; long y = point.y; GetImageXY(pDoc, ima, &x,&y); #ifndef VATI_EXTENSIONS RGBQUAD c = ima->RGBtoRGBQUAD(pDoc->m_color); c.rgbReserved=255; ima->DrawString(0,x,y,pDoc->m_text,c, pDoc->m_font.lfFaceName, pDoc->m_font.lfHeight, pDoc->m_font.lfWeight, pDoc->m_font.lfItalic, pDoc->m_font.lfUnderline, true); #else ima->DrawStringEx(0,x,y,&theApp.m_text ); #endif } Invalidate(0); } break; case 5: //flood fill { CxImage* ima = pDoc->GetImage(); if (ima){ DlgFloodFill* pDlg = ((CMainFrame *)(AfxGetApp()->m_pMainWnd))->m_pDlgFlood; if (pDlg){ pDlg->UpdateData(1); theApp.m_FloodColor = ima->RGBtoRGBQUAD(pDlg->m_color); theApp.m_FloodTolerance = pDlg->m_tol; theApp.m_FloodOpacity = pDlg->m_opacity; theApp.m_FloodSelect = pDlg->m_select; } pDoc->SubmitUndo(); long x = point.x; long y = point.y; GetImageXY(pDoc, ima, &x,&y); long yflip = ima->GetHeight() - y - 1; ima->FloodFill(x,yflip,theApp.m_FloodColor,theApp.m_FloodTolerance,theApp.m_FloodOpacity,theApp.m_FloodSelect!=0); Invalidate(0); } } break; } if (pDoc->GetWaitingClick()){ pDoc->SetWaitingClick(0); CxImage* ima = pDoc->GetImage(); if (ima) { long x = point.x; long y = point.y; GetImageXY(pDoc, ima, &x,&y); if (ima->IsInside(x,y)) { pDoc->SubmitUndo(); long yflip = ima->GetHeight() - y - 1; ima->SetTransIndex(ima->GetPixelIndex(x,yflip)); // <DP> RGB transparency ima->SetTransColor(ima->GetPixelColor(x,yflip)); pDoc->UpdateAllViews(NULL); } } } #if CXIMAGE_DEMO_SELECT else { KillTimer(1); pDoc->m_NumSel=0; m_SelShift=0; } #endif } CScrollView::OnLButtonDown(nFlags, point); }
////////////////////////////////////////////////////////////////////////////// // CDemoView message handlers ////////////////////////////////////////////////////////////////////////////// void CDemoView::OnMouseMove(UINT nFlags, CPoint point) { CDemoDoc* pDoc = GetDocument(); CxImage* ima = pDoc->GetImage(); if (!ima) return; // We'll get the RGB values at the point the user selects long x = point.x; long y = point.y; GetImageXY(pDoc, ima, &x,&y); TCHAR s[80]; if (ima->IsInside(x,y)) { long yflip = ima->GetHeight() - y - 1; _stprintf(s,_T("x: %d y: %d idx: %d"), x, y, ima->GetPixelIndex(x,yflip)); RGBQUAD rgb=ima->GetPixelColor(x,yflip); if (ima->AlphaIsValid()) rgb.rgbReserved=ima->AlphaGet(x,yflip); else rgb.rgbReserved=ima->GetPaletteColor(ima->GetPixelIndex(x,yflip)).rgbReserved; _stprintf(&s[_tcslen(s)],_T(" RGBA: (%d, %d, %d, %d)"), rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue, rgb.rgbReserved); //Enable these lines if you want draw over the image //if ((nFlags & MK_LBUTTON)==MK_LBUTTON){ // ima->SetPixelColor(x,yflip,RGB(rand()/(RAND_MAX/256),rand()/(RAND_MAX/256),rand()/(RAND_MAX/256))); // Invalidate(0); //} #ifdef VATI_EXTENSIONS if (nFlags & MK_RBUTTON && !(nFlags & MK_LBUTTON)) { switch (pDoc->m_tool){ case 1: // selection if ( nFlags & MK_CONTROL ) // CTRL+right button: move selection { for (int i=0; i<pDoc->m_NumSel; i++) { pDoc->m_Sel[i].x += (long)(x-m_oldPnt.x); pDoc->m_Sel[i].y += (long)(y-m_oldPnt.y); } m_oldPnt.x = x; m_oldPnt.y = y; //redraw selection CWnd* pFrame=GetParentFrame(); RECT rClient; pFrame->GetClientRect(&rClient); pFrame->RedrawWindow( &rClient, NULL, RDW_INVALIDATE | RDW_UPDATENOW); DrawSelection(); } else if ( !(nFlags & MK_CONTROL) && pDoc->m_isRectSel && pDoc->m_NumSel==5 ) { // calculate angle difference looking from rectangle center double d_angle = atan2( (y - m_orgPnt.y), (x - m_orgPnt.x) ) - atan2( (m_oldPnt.y - m_orgPnt.y), (m_oldPnt.x - m_orgPnt.x) ); m_oldPnt.x = x; m_oldPnt.y = y; Dpoint2d p; // rotate corner points around center point for(int i=0;i<5;i++) { p.x = m_dpnt[i].x - m_orgPnt.x; p.y = m_dpnt[i].y - m_orgPnt.y; m_dpnt[i].x = p.x*cos(d_angle) - p.y*sin(d_angle) + m_orgPnt.x; m_dpnt[i].y = p.x*sin(d_angle) + p.y*cos(d_angle) + m_orgPnt.y; // write back to selection pDoc->m_Sel[i].x = (long)m_dpnt[i].x ; pDoc->m_Sel[i].y = (long)m_dpnt[i].y ; } // redraw the rectangle CWnd* pFrame=GetParentFrame(); RECT rClient; pFrame->GetClientRect(&rClient); pFrame->RedrawWindow( &rClient, NULL, RDW_INVALIDATE | RDW_UPDATENOW); DrawSelection(); } break; } // end switch } // end if MK_RBUTTON #endif if (nFlags & MK_LBUTTON) switch (pDoc->m_tool){ case 0: // move { SetCursor(LoadCursor(0,IDC_SIZEALL)); CSize sz(GetTotalSize()); CWnd* pFrame=GetParentFrame(); RECT rClient; pFrame->GetClientRect(&rClient); if (sz.cx>rClient.right) SetScrollPos(SB_HORZ,m_RefScroll.x - point.x + m_RefPoint.x); else SetScrollPos(SB_HORZ,0); if (sz.cy>rClient.bottom) SetScrollPos(SB_VERT,m_RefScroll.y - point.y + m_RefPoint.y); else SetScrollPos(SB_VERT,0); Invalidate(0); break; } case 1: //selection SetCursor(LoadCursor(0,IDC_CROSS)); #if CXIMAGE_DEMO_SELECT #ifdef VATI_EXTENSIONS if ( nFlags & MK_SHIFT ) { // rectangle selection pDoc->m_isRectSel = 1; // in rectangle mode, selection array has 0,1 or 5 points if (!pDoc->m_NumSel) { pDoc->m_Sel[0].x = x; pDoc->m_Sel[0].y = y; pDoc->m_NumSel = 1; } else // already has at least one corner { pDoc->m_Sel[1].x = x; pDoc->m_Sel[1].y = pDoc->m_Sel[0].y; pDoc->m_Sel[2].x = x; pDoc->m_Sel[2].y = y; pDoc->m_Sel[3].x = pDoc->m_Sel[0].x; pDoc->m_Sel[3].y = y; //close the rectangle: pDoc->m_Sel[4].x = pDoc->m_Sel[0].x; pDoc->m_Sel[4].y = pDoc->m_Sel[0].y; pDoc->m_NumSel = 5; } // delete old rectangle from display: CWnd* pFrame=GetParentFrame(); RECT rClient; pFrame->GetClientRect(&rClient); pFrame->RedrawWindow( &rClient, NULL, RDW_INVALIDATE | RDW_UPDATENOW); // draw the new rectangle DrawSelection(); } else #endif { //freehand selection (original) float zoom=pDoc->GetZoomFactor(); CPoint pos(GetScrollPosition()); int i=pDoc->m_NumSel; pDoc->m_Sel[i].x = (long)((point.x + pos.x)/zoom); pDoc->m_Sel[i].y = (long)((point.y + pos.y)/zoom); if (i<(MAX_SEL_POINTS-2)) pDoc->m_NumSel++; DrawSelection(); } #endif } //end switch } else _tcscpy(s,_T(" ")); CStatusBar& statusBar = ((CMainFrame *)(AfxGetApp()->m_pMainWnd))->GetStatusBar(); statusBar.SetPaneText(0, s); CScrollView::OnMouseMove(nFlags, point); }