void QFObjectRenderer::copyFrame() { IClipboard clipboard(window_p->handle()); PBYTE frameBuffer; ULONG scanLineBytes, scanLines; BITMAPINFOHEADER2 bmp = {0}; BITMAPINFOHEADER2 bmpInfo; HBITMAP hbm; LONG errorCode; errorCode = DiveBeginImageBufferAccess(dive, frame[currentColumn][currentRow], &frameBuffer, &scanLineBytes, &scanLines); bmp.cbFix = sizeof(BITMAPINFOHEADER2); bmp.cx = movieSize().width(); bmp.cy = movieSize().height(); bmp.cPlanes = 1; bmp.cBitCount = 24; bmp.ulCompression = BCA_UNCOMP; bmp.cbImage = scanLineBytes * scanLines; bmp.usRecording = BRA_BOTTOMUP; /* Must be BRA_BOTTOMUP. */ bmp.usRendering = BRH_NOTHALFTONED; /* Not used. */ bmp.ulColorEncoding = BCE_RGB; bmpInfo = bmp; IGraphicContext context; hbm = GpiCreateBitmap(context.handle(), &bmp, CBM_INIT, frameBuffer, (PBITMAPINFO2)&bmpInfo); clipboard.setBitmap(hbm); GpiDeleteBitmap(hbm); errorCode = DiveEndImageBufferAccess(dive, frame[currentColumn][currentRow]); }
void QFObjectRenderer::captureFrame(IString saveAsFileName, FOURCC ioProc) { HMMIO frameFile; MMIOINFO info = {0}; LONG bytesWritten; MMIMAGEHEADER header = {0}; PBYTE frameBuffer; ULONG scanLineBytes, scanLines; LONG errorCode; info.fccIOProc = ioProc; info.ulTranslate = MMIO_TRANSLATEHEADER | MMIO_TRANSLATEDATA; errorCode = DiveBeginImageBufferAccess(dive, frame[currentColumn][currentRow], &frameBuffer, &scanLineBytes, &scanLines); header.ulHeaderLength = sizeof(MMIMAGEHEADER); header.ulContentType = MMIO_IMAGE_PHOTO; header.ulMediaType = MMIO_MEDIATYPE_IMAGE; header.mmXDIBHeader.XDIBHeaderPrefix.ulMemSize = scanLineBytes * scanLines; /* Length of bitmap. */ header.mmXDIBHeader.XDIBHeaderPrefix.ulPelFormat = FOURCC_BGR3; /* FOURCC code defining the pel format. */ header.mmXDIBHeader.BMPInfoHeader2.cbFix = sizeof (BITMAPINFOHEADER2); header.mmXDIBHeader.BMPInfoHeader2.cx = movieSize().width(); header.mmXDIBHeader.BMPInfoHeader2.cy = movieSize().height(); header.mmXDIBHeader.BMPInfoHeader2.cPlanes = 1; /* Number of planes. */ header.mmXDIBHeader.BMPInfoHeader2.cBitCount = 24; /* Bits per pel. */ header.mmXDIBHeader.BMPInfoHeader2.ulCompression = BCA_UNCOMP; header.mmXDIBHeader.BMPInfoHeader2.cbImage = header.mmXDIBHeader.XDIBHeaderPrefix.ulMemSize; header.mmXDIBHeader.BMPInfoHeader2.usRecording = BRA_BOTTOMUP; /* Must be BRA_BOTTOMUP. */ header.mmXDIBHeader.BMPInfoHeader2.usRendering = BRH_NOTHALFTONED; /* Not used. */ frameFile = mmioOpen(saveAsFileName, &info, MMIO_CREATE | MMIO_WRITE); mmioSetHeader(frameFile, &header, sizeof(MMIMAGEHEADER), &bytesWritten, 0, 0); mmioWrite(frameFile, frameBuffer, header.mmXDIBHeader.XDIBHeaderPrefix.ulMemSize); mmioClose(frameFile, 0); errorCode = DiveEndImageBufferAccess(dive, frame[currentColumn][currentRow]); }
void QFObjectRenderer::prepareFrame(ULONG column, ULONG row, ULONG length) { LONG errorCode; PBYTE convertedBuffer; ULONG scanLineBytes, scanLines; // Decompress frame into codec-format buffer videoSetup->decompress.ulSrcBufLen = length; videoSetup->decompress.pSrcBuf = videoSetup->compressedFrame; videoSetup->decompress.ulDstBufLen = 0; errorCode = DiveBeginImageBufferAccess(diveForLoading, videoSetup->decompressedFrame, (PBYTE*)&videoSetup->decompress.pDstBuf, &scanLineBytes, &scanLines); errorCode = videoSetup->sendCodecMessage(&videoSetup->codecHandle, MMIOM_CODEC_DECOMPRESS, (LONG)&videoSetup->decompress, 0); if (videoSetup->colorFormat == FOURCC_BGR3) { PBYTE bufferSpot = buffer[column][row] = new BYTE[scanLineBytes * videoSetup->rectl.yTop]; for (int line = 0; line < videoSetup->rectl.yTop; line++) //Invert codec output memcpy(bufferSpot + line * scanLineBytes, (PBYTE)(videoSetup->decompress.pDstBuf) + (videoSetup->rectl.yTop - line - 1) * scanLineBytes, scanLineBytes); errorCode = DiveEndImageBufferAccess(diveForLoading, videoSetup->decompressedFrame); } else { errorCode = DiveEndImageBufferAccess(diveForLoading, videoSetup->decompressedFrame); errorCode = DiveBlitImage(diveForLoading, videoSetup->decompressedFrame, videoSetup->convertedFrame); errorCode = DiveBeginImageBufferAccess(diveForLoading, videoSetup->convertedFrame, &convertedBuffer, &scanLineBytes, &scanLines); buffer[column][row] = new BYTE[scanLineBytes * videoSetup->rectl.yTop]; memcpy(buffer[column][row], convertedBuffer + (scanLines - videoSetup->rectl.yTop) * scanLineBytes, scanLineBytes * videoSetup->rectl.yTop); errorCode = DiveEndImageBufferAccess(diveForLoading, videoSetup->convertedFrame); } // Create permanent run-time buffer from regular buffer errorCode = DiveAllocImageBuffer(dive, &frame[column][row], FOURCC_BGR3, movieSize().width(), movieSize().height(), scanLineBytes, buffer[column][row]); }
//-------------------------------------------------------------- void ofApp::setup() { ofDirectory dir; ofVideoPlayer player; int edge = 2; ofxXmlSettings settings; settings.loadFile("settings.xml"); ofVec2f movieSize(settings.getValue("movieSize:width", 128) + edge, settings.getValue("movieSize:height", 128) + edge); ofVec2f texSize(settings.getValue("texSize:width", 1024), settings.getValue("texSize:height", 1024)); float duration = settings.getValue("duration", 1.0); float fps = settings.getValue("fps", 1.0); int numFrames = duration * fps; int numMovies = dir.listDir("movies"); int totalFrames = numFrames * numMovies; float movieRatio = movieSize.x / movieSize.y; float texArea = texSize.x * texSize.y; float fitArea = texArea / (float)totalFrames; float fitHeight = sqrt(fitArea/movieRatio); float fitWidth = fitArea/fitHeight; ofVec2f fitSize(fitWidth, fitHeight); ofVec2f numUnits(ceil(texSize.x / fitSize.x), ceil(texSize.y / fitSize.y)); ofVec2f size = texSize / numUnits; ofVec2f scale = movieSize / size; ofFile::removeFile("sprite.js"); ofstream js; js.open (ofToDataPath("sprite.js").c_str(), std::ios::out | std::ios::app); js << "var sprite={coordinates:["; ofFbo fbo; fbo.allocate(texSize.x, texSize.y); fbo.begin(); ofClear(0, 0, 0, 0); fbo.end(); float column = -1; float row = -1; int frameIndex = 0; for (float i = 0; i < numMovies; i++) { player.loadMovie(dir.getPath(i)); cout << dir.getPath(i) << endl; int playerNumFrames = player.getTotalNumFrames(); float offset = (float)playerNumFrames / (float)numFrames; js << "["; for (float j = 0; j < numFrames; j++) { column = frameIndex % (int)numUnits.x; if(column == 0) row++; js << "\"-" << (column * movieSize.x) << "px -" << (row * movieSize.y) << "px\""; if(j < numFrames-1) js << ","; player.setFrame(j * offset+1); player.update(); fbo.begin(); player.draw(floor(column * size.x), floor(row * size.y), ceil(size.x), ceil(size.y)); fbo.end(); frameIndex++; } js << "]"; if(i < numMovies-1) js << ","; } js << "]"; js << ",duration:" << duration; js << ",image:\"sprite.png\""; js << ",numFrames:" << numFrames; js << ",numMovies:" << numMovies; js << ",width:" << movieSize.x - edge; js << ",height:" << movieSize.y - edge; js << ",backgroundSize:\"" << (texSize.x * scale.x) << "px " << (texSize.y * scale.y)<< "px\""; js << "};"; js.close(); ofPixels pixels; pixels.allocate(texSize.x, texSize.y, 4); fbo.readToPixels(pixels); ofSaveImage(pixels, "sprite.png"); ofExit(0); }