📄 rgbimutil.cpp
字号:
// $image\rgbimutil.cpp 1.5 milbo$ image utilities// Warning: this is raw research code -- expect it to be quite messy.// milbo durban dec05#include <windows.h>#include <io.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>#include <signal.h>#include <float.h>#include <math.h>#include <new.h>#include <direct.h>#include <sys/stat.h>#include <fstream.h>#include <iostream.h>#include "mcommon.hpp"#include "mfile.hpp"#include "image.hpp"#include "imutil.hpp"#include "rgbimutil.hpp"#include "imfile.hpp"#include "jpegutil.hpp"#include "ezfont.h"//-----------------------------------------------------------------------------void MoveRgbImage (RgbImage &Img, // io int nxShift, int nyShift, bool fVerbose, bool fExtend) // in{int width = Img.width;int height = Img.height;if (fVerbose) { if (nxShift) lprintf("xShift %d ", nxShift); if (nyShift) lprintf("yShift %d ", nyShift); }if (abs(nxShift) >= width) Err("xShift %d is bigger than width %d", nxShift, Img.width);if (abs(nyShift) >= height) Err("yShift %d is bigger than height %d", nyShift, Img.height);RgbImage OutImg(Img.width, Img.height, true); // fills image with blackfor (int ix = 0; ix < width; ix++) for (int iy = 0; iy < height; iy++) { int ixOld = ix - nxShift; for (int iy = 0; iy < height; iy++) { int iyOld = iy - nyShift; if (ixOld < 0) { if (fExtend) ixOld = 0; else continue; } else if (ixOld >= width) { if (fExtend) ixOld = width-1; else continue; } if (iyOld < 0) { if (fExtend) iyOld = 0; else continue; } else if (iyOld >= height) { if (fExtend) iyOld = height-1; else continue; } OutImg(ix, iy) = Img(ixOld, iyOld); } }Img = OutImg;}//-----------------------------------------------------------------------------void CropRgbImage (RgbImage &Img, // io int nTopCrop, int nBottomCrop, int nLeftCrop, int nRightCrop, // in bool fVerbose, bool fWidthDivisibleBy4) // in{int width = Img.width;int height = Img.height;if (fWidthDivisibleBy4) nLeftCrop += (Img.width - nRightCrop - nLeftCrop) % 4; // ensure width is divisble by 4if (fVerbose) { if (nTopCrop) lprintf("CropTop %d ", nTopCrop); if (nBottomCrop) lprintf("CropBottom %d ", nBottomCrop); if (nLeftCrop) lprintf("CropLeft %d ", nLeftCrop); if (nRightCrop) lprintf("CropRight %d ", nRightCrop); }int nNewWidth = Img.width - nLeftCrop - nRightCrop;int nNewHeight = Img.height - nTopCrop - nBottomCrop;if (nTopCrop < 0 || nBottomCrop < 0 || nLeftCrop < 0 || nRightCrop < 0) Err("you can't specify a crop less than 0");if (nNewWidth <= 0) Err("specified left or right crop would cause a width less than or equal to zero");if (nNewWidth > width) Err("specified left or right crop would cause a width bigger than current width");if (nNewHeight <= 0) Err("specified top or bottom crop would cause a height less than or equal to zero");if (nNewHeight > height) Err("specified top or bottom crop would cause a height bigger than current height");RgbImage OutImg(nNewWidth, nNewHeight);for (int iy = 0; iy < nNewHeight; iy++) for (int ix = 0; ix < nNewWidth; ix++) OutImg(ix, iy) = Img(ix + nLeftCrop, iy + nBottomCrop);Img = OutImg;}//-----------------------------------------------------------------------------void CropRgbImageSoWidthIsDivisbleBy4 (RgbImage &Img, // io bool fVerbose) // in{if (Img.width % 4) CropRgbImage(Img, 0, 0, 0, 0, fVerbose, IM_WIDTH_DIVISIBLE_BY_4);}//-----------------------------------------------------------------------------// Will flip horizontally, unless fVertical is true in which case it will flip verticallyvoid FlipRgbImage (RgbImage &Img, // io bool fVertical, bool fVerbose) // in{int width = Img.width;int height = Img.height;if (fVerbose) lprintf("Flip%s ", (fVertical? "Vertical": "Horizontal"));RgbImage OutImg(width, height);if (fVertical) SysErr("FlipImage vertical not yet implemented");else for (int iy = 0; iy < height; iy++) { int ix1 = width; for (int ix = 0; ix < width; ix++) OutImg(ix + (iy * width)) = Img(--ix1 + (iy * width)); }Img = OutImg;}//-----------------------------------------------------------------------------// Special case of ScaleRgbImage: scale up by an integral amount in each direction// This is much faster than the standard ScaleRgbImage#if 0 // no longer neededstatic void ScaleUpRgbImage (RgbImage &Img, // io int widthScale, int heightScale) // in{int width = Img.width * widthScale;int height = Img.height * heightScale;RgbImage OutImg(width, height);for (int iy = 0; iy < height; iy += heightScale) for (int ix = 0; ix < width; ix += widthScale) for (int i = 0; i < widthScale; i++) for (int j = 0; j < heightScale; j++) OutImg(ix+i, iy+j) = Img(ix/widthScale + iy/heightScale * width/widthScale);Img = OutImg;}#endif//-----------------------------------------------------------------------------// Helper function for ScaleRgbImage// TODO turn this into a macro? inlining here is possibly ignored by MS compilerstatic inline tRGB InterpolateRgbPixel (const tRGB *pIn, int ix, double Scale, int Max) // in{int iPos = (int)(ix * Scale);int iPos1 = iPos + 1;if (iPos1 >= Max) // don't overrun buffer iPos1 = Max-1;tRGB Rgb;for (int iColor = 0; iColor < 3; iColor++) { int c0, c1; switch (iColor) { case 0: c0 = pIn[iPos].Red; c1 = pIn[iPos1].Red; break; case 1: c0 = pIn[iPos].Green; c1 = pIn[iPos1].Green; break; default: c0 = pIn[iPos].Blue; c1 = pIn[iPos1].Blue; break; } double Frac = (ix * Scale) - iPos; double Value = (1.0 - Frac) * c0 + Frac * c1; // linear interpolation byte iValue = byte(Value + 0.5); switch (iColor) { case 0: Rgb.Red = iValue; break; case 1: Rgb.Green = iValue; break; default: Rgb.Blue = iValue; break; } }return Rgb;}//-----------------------------------------------------------------------------// Scale using two steps of linear interpolation: first in the X direction, // then in the Y direction//// If fBilinear is false we use the nearest pixel (and get a sharper image)//// Is the following a bug? If size is reduced by more than 2, this ignores some // pixels in the input image, even when fBilinear is true -- because we look// a max of 2 pixels when doing bilinear interpretation. // Use ReduceRgbImage if this matters to you.//// I lifted the original version of this from Henry Rowley img.cc:ReduceSize()void ScaleRgbImage (RgbImage &Img, // io int nNewWidth, int nNewHeight, bool fVerbose, bool fBilinear) // in{int ix, iy;int width = Img.width;int height = Img.height;double scaleX = (double)width /nNewWidth;double scaleY = (double)height/nNewHeight;if (fVerbose) { if (scaleX > 1) lprintf("ScaleDown %.2g ", 1/scaleX); else if (scaleX < 1) lprintf("ScaleUp %.2g ", 1/scaleX); else lprintf("Scale %.2g ", 1/scaleX); }if (width == nNewWidth && height == nNewHeight) return; // NOTE: RETURNif (!fBilinear) { // use nearest pixel RgbImage OutImg(nNewWidth, nNewHeight); for (iy = 0; iy < nNewHeight; iy++) for (ix = 0; ix < nNewWidth; ix++) OutImg(ix, iy) = Img((ix * width) / nNewWidth, (iy * height) / nNewHeight); Img = OutImg; }else { // scale horizontally RgbImage Out1(height, nNewWidth); tRGB *pIn = Img.buf; for (iy = 0; iy < height; iy++) { for (ix = 0; ix < nNewWidth; ix++) Out1(iy + ix * height) = InterpolateRgbPixel(pIn, ix, scaleX, width); pIn += width; } // scale vertically
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -