BOOL fipImage::copySubImage(fipImage& dst, int left, int top, int right, int bottom) const { if(_dib) { dst = FreeImage_Copy(_dib, left, top, right, bottom); return dst.isValid(); } return FALSE; }
BOOL fipImage::crop(int left, int top, int right, int bottom) { if(_dib) { FIBITMAP *dst = FreeImage_Copy(_dib, left, top, right, bottom); return replace(dst); } return FALSE; }
VALUE rb_graffik_cropped_thumbnail(VALUE self, VALUE rb_size) { // Convert the Ruby numbers to C numbers int size = FIX2INT(rb_size); // Load our image FIBITMAP *image = get_instance_image(self); // Get dimensions int width = FreeImage_GetWidth(image), height = FreeImage_GetHeight(image); int left = 0, top = 0, right = width, bottom = height; int half = (width - height) / 2; if (width > height) { left = half; right = half + height; } if (height > width) { top = half; bottom = half + width; } // Crop the image FIBITMAP *cropped = FreeImage_Copy(image, left, top, right, bottom); // Resize the image FIBITMAP *thumbnail = FreeImage_MakeThumbnail(cropped, size, TRUE); // Create a new instance for Ruby VALUE instance = Data_Wrap_Struct(CLASS_OF(self), NULL, NULL, thumbnail); rb_iv_set(instance, "@file_type", rb_iv_get(self, "@file_type")); // If a block is given, yield to it, if not, return the instance if (rb_block_given_p()) { return rb_ensure(rb_yield, instance, rb_graffik_close, instance); } else { return instance; } }
/** Poisson solver based on a multigrig algorithm. This routine solves a Poisson equation, remap result pixels to [0..1] and returns the solution. NB: The input image is first stored inside a square image whose size is (2^j + 1)x(2^j + 1) for some integer j, where j is such that 2^j is the nearest larger dimension corresponding to MAX(image width, image height). @param Laplacian Laplacian image @param ncycle Number of cycles in the multigrid algorithm (usually 2 or 3) @return Returns the solved PDE equations if successful, returns NULL otherwise */ FIBITMAP* DLL_CALLCONV FreeImage_MultigridPoissonSolver(FIBITMAP *Laplacian, int ncycle) { if(!Laplacian) return NULL; int width = FreeImage_GetWidth(Laplacian); int height = FreeImage_GetHeight(Laplacian); // get nearest larger dimension length that is acceptable by the algorithm int n = MAX(width, height); int size = 0; while((n >>= 1) > 0) size++; // size must be of the form 2^j + 1 for some integer j size = 1 + (1 << (size + 1)); // allocate a temporary square image I FIBITMAP *I = FreeImage_AllocateT(FIT_FLOAT, size, size); if(!I) return NULL; // copy Laplacian into I and shift pixels to create a boundary FreeImage_Paste(I, Laplacian, 1, 1, 255); // solve the PDE equation fmg_mglin(I, size, ncycle); // shift pixels back FIBITMAP *U = FreeImage_Copy(I, 1, 1, width + 1, height + 1); FreeImage_Unload(I); // remap pixels to [0..1] NormalizeY(U, 0, 1); // return the integrated image return U; }
bitmap_ptr finalize(bool showProgress = true) { if (chunks.empty()) { return nullptr; } if (showProgress) { std::cout << "Adding all accepted chunks to the final image\n"; } const auto it = chunks.begin(); bitmap_ptr firstChunk = GenericLoader(*it); auto currentHeight = 0; const auto type = FreeImage_GetImageType(firstChunk.get()); const auto bpp = FreeImage_GetBPP(firstChunk.get()); bitmap_ptr finalImage(FreeImage_AllocateT(type, width, height, bpp)); auto RGBChunkWorker = [=, &finalImage, ¤tHeight](const std::string& el) { bitmap_ptr chunk = GenericLoader(el); auto chunkHeight = FreeImage_GetHeight(chunk.get()); auto chunk_img = FreeImage_Copy(chunk.get(), 0, 0, this->width, chunkHeight); if (chunk_img) { FreeImage_Paste(finalImage.get(), chunk_img, 0, currentHeight, 256); } currentHeight += chunkHeight; }; std::for_each(chunks.begin(), chunks.end(), RGBChunkWorker); return finalImage; }
/* * Arguments: dest. dib_udata, source dib_udata, * left (number), top (number), right (number), bottom (number) * Returns: [dest. dib_udata] */ static int dib_copy (lua_State *L) { FIBITMAP **dibp = checkudata(L, 1, DIB_TYPENAME); FIBITMAP *dib = lua_unboxpointer(L, 2, DIB_TYPENAME); const int left = lua_tointeger(L, 3); const int top = lua_tointeger(L, 4); const int right = lua_tointeger(L, 5); const int bottom = lua_tointeger(L, 6); *dibp = FreeImage_Copy(dib, left, top, right, bottom); return dib_checkerror(L, *dibp); }
static VALUE with_crop(VALUE self, VALUE _l, VALUE _t, VALUE _r, VALUE _b) { int l = FIX2INT(_l); int t = FIX2INT(_t); int r = FIX2INT(_r); int b = FIX2INT(_b); FIBITMAP *copy; VALUE result = Qnil; GET_BITMAP(bitmap); if (copy = FreeImage_Copy(bitmap, l, t, r, b)) { copy_icc_profile(self, bitmap, copy); result = wrap_and_yield(copy, self, 0); } return (result); }
VALUE rb_graffik_crop(VALUE self, VALUE rb_left, VALUE rb_top, VALUE rb_right, VALUE rb_bottom) { // Convert Ruby numbers to C numbers int top = FIX2INT(rb_top), right = FIX2INT(rb_right), bottom = FIX2INT(rb_bottom), left = FIX2INT(rb_left); // Load our image and specifiy where to put the copy FIBITMAP *image = get_instance_image(self); // Crop the image FIBITMAP *cropped = FreeImage_Copy(image, left, top, right, bottom); // Create a new instance for Ruby VALUE instance = Data_Wrap_Struct(CLASS_OF(self), NULL, NULL, cropped); rb_iv_set(instance, "@file_type", rb_iv_get(self, "@file_type")); // If a block is given, yield to it, if not, return the instance if (rb_block_given_p()) { return rb_ensure(rb_yield, instance, rb_graffik_close, instance); } else { return instance; } }
// Transmits a partial frame of imagery to the client int sendPartialFrame(SOCKET &clientSocket, unsigned int x, unsigned int y, unsigned int width, unsigned int height) { int status = 0; FIBITMAP *fiImage; FIBITMAP *fiImage24; FIMEMORY *fiBuffer; // Signal that a new frame is required and wait for frame InterlockedExchange( &g_lRequestFlag, TRUE ); g_pRequestEvent->waitFor(); // Enter critical section for frame buffer from UT2004 // and copy new raw image to local buffer EnterCriticalSection( &g_CriticalSection ); { fiImage = FreeImage_Copy(g_fiImage, x, y, x + width, y + height); } LeaveCriticalSection( &g_CriticalSection ); // Convert new image to 24 bits fiImage24 = FreeImage_ConvertTo24Bits(fiImage); // Create memory reference fiBuffer = FreeImage_OpenMemory(); // Convert a raw frame to a useful image status = writeFrame( fiBuffer, fiImage24, g_iImageType ); if (status != 1) status = 0; // TODO: handle error here // Transmit frame over socket status = transmitFrame( fiBuffer, clientSocket, g_iImageType ); // Delete memory references FreeImage_Unload( fiImage ); FreeImage_Unload( fiImage24 ); FreeImage_CloseMemory( fiBuffer ); return status; }
FOX_DLL unsigned gifsplit(char * pngprefix, char gifpath[MAXGIFCOUNT][MAXPATHCHAR], unsigned gifPathCount, unsigned ScreenWidth, unsigned ScreenHeight, unsigned bSaveToBuff, FIBITMAP * hImageList[MAXOUTBUFCOUNT]) // 1 base count { // ------ 声明开始 // FIBITMAP * hImageList[MAXOUTBUFCOUNT] ; // 输出 himage 数组, 首元素包含数组长度 FIBITMAP * hPicTemplete; FIBITMAP * hImage ; FIBITMAP * hPicBlank; BYTE * pBit ; unsigned ImgPitch, ImgWidth, ImgHeight ; char pathPNG[MAXPATHCHAR]; unsigned n; // ylist unsigned xsplitcount = 0 ; // X 切割份数 POSLIST ylist[MAXYLIST] ; unsigned TextLineCount = 0 ; // Y 切割份数 LineLR yinfo[MAXYLIST] ; unsigned StartX, EndX ; // joblist JOBLIST joblist[MAXJOBLIST] ; unsigned NowJobCount ; // joblist item count unsigned nNewPicCount = 0 ; // ------- 语句开始 hImage = gifcat(gifpath, gifPathCount) ; // 将多张图片连接为一张图片 hPicTemplete = CreateTemplete(hImage, ScreenWidth, ScreenHeight) ; // 创建空白PNG模版 ImgWidth = FreeImage_GetWidth(hImage) ; ImgHeight = FreeImage_GetHeight(hImage) ; ImgPitch = FreeImage_GetPitch(hImage) ; pBit = FreeImage_GetBits(hImage) ; TextLineCount = GetYList(ylist , pBit , ImgPitch, ImgWidth, ImgHeight) ; // 获取 Y 分割列表 StartX = GetLeftBorderX(0, ImgWidth, 0, ImgHeight, pBit, ImgPitch) ; EndX = GetRightBorderX(ImgWidth - 1, ImgWidth, 0, ImgHeight, pBit, ImgPitch) ; yinfo[0].left = StartX ; yinfo[0].right = EndX ; GetLineBorder(yinfo, ylist, TextLineCount, pBit, ImgPitch, ImgWidth, ImgHeight) ; // 每行左右坐标 yinfo[TextLineCount].left = StartX ; yinfo[TextLineCount].right = EndX ; NowJobCount = NewGetJobList(joblist, yinfo, ylist, TextLineCount, ScreenWidth, ScreenHeight, ImgWidth, ImgHeight, pBit, ImgPitch, bSaveToBuff) ; // 新版任务列表,只根据屏幕宽度取X坐标,不固定 // 根据joblist 来生成 png for (n = 0; n < NowJobCount; n++) { // printf("任务编号: %d , A: %d , L: %d , R: %d , T: %d , B: %d , nL: %d , nT: %d, R-L: %d\n", n, joblist[n].action, joblist[n].left, joblist[n].right, joblist[n].top, joblist[n].bottom, joblist[n].newleft, joblist[n].newtop, joblist[n].right - joblist[n].left) ; // 调试用 if ( ( joblist[n].action >= 1 ) && ( joblist[n].action != 5 ) ) hPicBlank = FreeImage_Clone(hPicTemplete); FreeImage_Paste(hPicBlank, FreeImage_Copy(hImage, joblist[n].left, joblist[n].top, joblist[n].right, joblist[n].bottom), joblist[n].newleft, joblist[n].newtop, 300); if ( joblist[n].action >= 5 ) { ++nNewPicCount ; sprintf(pathPNG, "%s%03d.png", pngprefix, nNewPicCount) ; printf("生成PNG %d : %s\n", nNewPicCount , pathPNG) ; if ( bSaveToBuff == 1 ) { // 输出到buff hImageList[nNewPicCount-1] = hPicBlank ; } else { // 输出到文件 FreeImage_Save(FIF_PNG, hPicBlank, pathPNG) ; FreeImage_Unload(hPicBlank) ; } } } return nNewPicCount; }
bitmap_ptr finalize(bool showProgress = false) { if (chunks.empty()) { return nullptr; } if (showProgress) { std::cout << "Adding all accepted chunks to the final image\n"; } const auto it = chunks.begin(); bitmap_ptr firstChunk = GenericLoader(*it); const auto type = FreeImage_GetImageType(firstChunk.get()); bitmap_ptr finalImage(FreeImage_Copy(firstChunk.get(), 0, height, width, 0)); auto RGBChunkWorker = [=, &finalImage](const std::string& el) { bitmap_ptr chunk = GenericLoader(el); auto chunkHeight = FreeImage_GetHeight(chunk.get()); for (unsigned int y = 0; y < chunkHeight; ++y) { auto srcbits = reinterpret_cast<FIRGBF *>(FreeImage_GetScanLine(chunk.get(), y)); auto dstbits = reinterpret_cast<FIRGBF *>(FreeImage_GetScanLine(finalImage.get(), y)); for (unsigned int x = 0; x < this->width; ++x) { dstbits[x].red += srcbits[x].red; dstbits[x].blue += srcbits[x].blue; dstbits[x].green += srcbits[x].green; } } }; auto RGBAChunkWorker = [=, &finalImage](const std::string& el) { bitmap_ptr chunk = GenericLoader(el); auto chunkHeight = FreeImage_GetHeight(chunk.get()); for (unsigned int y = 0; y < chunkHeight; ++y) { const auto srcbits = reinterpret_cast<FIRGBAF *>(FreeImage_GetScanLine(chunk.get(), y)); auto dstbits = reinterpret_cast<FIRGBAF *>(FreeImage_GetScanLine(finalImage.get(), y)); for (unsigned int x = 0; x < this->width; ++x) { dstbits[x].red += srcbits[x].red; dstbits[x].blue += srcbits[x].blue; dstbits[x].green += srcbits[x].green; dstbits[x].alpha += srcbits[x].alpha; } } }; auto alphaChunksWorker = [this, &finalImage](const std::string& el) { bitmap_ptr chunk = GenericLoader(el); auto chunkHeight = FreeImage_GetHeight(chunk.get()); for (unsigned int y = 0; y < chunkHeight; ++y) { const auto srcbits = reinterpret_cast<FIRGBAF *>(FreeImage_GetScanLine(chunk.get(), y)); auto dstbits = reinterpret_cast<FIRGBAF *>(FreeImage_GetScanLine(finalImage.get(), y)); for (unsigned int x = 0; x < this->width; ++x) { dstbits[x].alpha += srcbits[x].red + srcbits[x].blue + srcbits[x].green; } } }; if (type == FIT_RGBF) std::for_each(std::next(chunks.begin()), chunks.end(), RGBChunkWorker); else if (type == FIT_RGBAF) std::for_each(std::next(chunks.begin()), chunks.end(), RGBAChunkWorker); std::for_each(alphaChunks.begin(), alphaChunks.end(), alphaChunksWorker); return finalImage; }
static INT_PTR serviceBmpFilterResizeBitmap(WPARAM wParam,LPARAM lParam) { BITMAP bminfo; int width, height; int xOrig, yOrig, widthOrig, heightOrig; ResizeBitmap *info = (ResizeBitmap *) wParam; if (info == NULL || info->size != sizeof(ResizeBitmap) || info->hBmp == NULL || info->max_width < 0 || info->max_height < 0 || (info->fit & ~RESIZEBITMAP_FLAG_DONT_GROW) < RESIZEBITMAP_STRETCH || (info->fit & ~RESIZEBITMAP_FLAG_DONT_GROW) > RESIZEBITMAP_MAKE_SQUARE) return 0; // Well, lets do it // Calc final size GetObject(info->hBmp, sizeof(bminfo), &bminfo); width = info->max_width == 0 ? bminfo.bmWidth : info->max_width; height = info->max_height == 0 ? bminfo.bmHeight : info->max_height; xOrig = 0; yOrig = 0; widthOrig = bminfo.bmWidth; heightOrig = bminfo.bmHeight; if (widthOrig == 0 || heightOrig == 0) return 0; switch(info->fit & ~RESIZEBITMAP_FLAG_DONT_GROW) { case RESIZEBITMAP_STRETCH: { // Do nothing break; } case RESIZEBITMAP_KEEP_PROPORTIONS: { if (height * widthOrig / heightOrig <= width) { if (info->fit & RESIZEBITMAP_FLAG_DONT_GROW) height = min(height, bminfo.bmHeight); width = height * widthOrig / heightOrig; } else { if (info->fit & RESIZEBITMAP_FLAG_DONT_GROW) width = min(width, bminfo.bmWidth); height = width * heightOrig / widthOrig; } break; } case RESIZEBITMAP_MAKE_SQUARE: { if (info->fit & RESIZEBITMAP_FLAG_DONT_GROW) { width = min(width, bminfo.bmWidth); height = min(height, bminfo.bmHeight); } width = height = min(width, height); // Do not break. Use crop calcs to make size } case RESIZEBITMAP_CROP: { if (heightOrig * width / height >= widthOrig) { heightOrig = widthOrig * height / width; yOrig = (bminfo.bmHeight - heightOrig) / 2; } else { widthOrig = heightOrig * width / height; xOrig = (bminfo.bmWidth - widthOrig) / 2; } break; } } if ((width == bminfo.bmWidth && height == bminfo.bmHeight) || ((info->fit & RESIZEBITMAP_FLAG_DONT_GROW) && !(info->fit & RESIZEBITMAP_MAKE_SQUARE) && width > bminfo.bmWidth && height > bminfo.bmHeight)) { // Do nothing return (INT_PTR)info->hBmp; } else { FIBITMAP *dib = FreeImage_CreateDIBFromHBITMAP(info->hBmp); if (dib == NULL) return NULL; FIBITMAP *dib_tmp; if (xOrig > 0 || yOrig > 0) dib_tmp = FreeImage_Copy(dib, xOrig, yOrig, xOrig + widthOrig, yOrig + heightOrig); else dib_tmp = dib; if (dib_tmp == NULL) { FreeImage_Unload(dib); return NULL; } FIBITMAP *dib_new = FreeImage_Rescale(dib_tmp, width, height, FILTER_CATMULLROM); HBITMAP bitmap_new = FreeImage_CreateHBITMAPFromDIB(dib_new); if (dib_new != dib_tmp) FreeImage_Unload(dib_new); if (dib_tmp != dib) FreeImage_Unload(dib_tmp); FreeImage_Unload(dib); return (INT_PTR)bitmap_new; } }
FIBITMAP* finalize(bool showProgress = false) { if (chunks.empty()) { return NULL; } if (showProgress) { printf("Adding all accepted chunks to the final image\n"); } std::list<FIBITMAP*>::iterator it = chunks.begin(); unsigned int width = FreeImage_GetWidth(*it); unsigned int height = FreeImage_GetHeight(*it); FIBITMAP *finalImage = FreeImage_Copy(*it, 0, height, width, 0); for (it++; it != chunks.end(); it++) { for(unsigned int y = 0 ; y < height ; y++) { FIRGBAF *srcbits = (FIRGBAF *) FreeImage_GetScanLine(*it, y); FIRGBAF *dstbits = (FIRGBAF *) FreeImage_GetScanLine(finalImage, y); for(unsigned int x = 0 ; x < width ; x++) { dstbits[x].red += srcbits[x].red; dstbits[x].blue += srcbits[x].blue; dstbits[x].green += srcbits[x].green; } } } /* unsigned int numParts = chunks.size(); unsigned int chunkHeight = 12; unsigned int chunkWidth = 427; unsigned int lastHeight = height -1 - chunkHeight; unsigned int lastWidth = chunkWidth; unsigned int restWidth = chunkWidth; for (it++; it != chunks.end(); it++) { printf("lastHeight = %d, lastWidth = %d restWidth = %d\n", lastHeight, lastWidth, restWidth); bool continueChunk = true; while (continueChunk) { printf("lastHeight = %d, lastWidth = %d restWidth = %d\n", lastHeight, lastWidth, restWidth); continueChunk = false; for(unsigned int y = lastHeight ; y < min(height, lastHeight + chunkHeight + 1) ; y++) { FIRGBAF *srcbits = (FIRGBAF *) FreeImage_GetScanLine(*it, y); FIRGBAF *dstbits = (FIRGBAF *) FreeImage_GetScanLine(finalImage, y); for(unsigned int x = lastWidth ; x < min(width, lastWidth + restWidth) ; x++) { //printf("y = %d x= %d\n", y, x); dstbits[x].red = srcbits[x].red; dstbits[x].green = srcbits[x].green; dstbits[x].blue = srcbits[x].blue; } } if (width < lastWidth + restWidth) { continueChunk = true; lastHeight -= chunkHeight - 1; restWidth -= width - lastWidth; lastWidth = 0; } else { lastWidth += restWidth; restWidth = chunkWidth; } } }*/ return finalImage; }