rectstretch.cpp
来自「barcode readers [ from Image]」· C++ 代码 · 共 148 行
CPP
148 行
//
// RectStretch
// Stretches a rectangle in the input image into a new image of
// a specified size. The output size must be larger than the
// input. Bilinear interpolation is used.
//
// Copyright (C) 2006 by Jon A. Webb (Contact via GMail; username is jonawebb)
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#include "RectStretch.h"
#include "Debug.h"
#include "GrayImageIter.h"
#include "GrayIndex.h"
#include "Image.h"
#include <e32math.h>
using namespace Core;
namespace Algorithm
{
EXPORT_C CRectStretch* CRectStretch::NewL(
TRect inputRect,
TSize outputSize)
{
CRectStretch* pMe = new (ELeave)
CRectStretch(inputRect, outputSize);
CleanupStack::PushL(pMe);
pMe->ConstructL();
CleanupStack::Pop(pMe);
return pMe;
}
CRectStretch::CRectStretch(
TRect inputRect,
TSize outputSize) :
ibEmpty(true),
iRect(inputRect),
iSize(outputSize)
{
}
void CRectStretch::ConstructL()
{
__ASSERT_DEBUG(
iRect.Width() <= iSize.iWidth &&
iRect.Height() <= iSize.iHeight,
User::Invariant());
iImage = CImage::NewL(iSize.iWidth, iSize.iHeight, EGray256);
}
CRectStretch::~CRectStretch(void)
{
}
CImage CRectStretch::FrontL()
{
if (ibEmpty) {
User::Leave(KErrGeneral);
return CImage();
}
ibEmpty = true;
return iImage;
}
void CRectStretch::PushL(CImage image)
{
IImageSize size(image);
// assert rectangle is inside the input image
__ASSERT_DEBUG(iRect.iBr.iX <= size.Width() &&
iRect.iBr.iY <= size.Height(),
User::Invariant());
image.LockLC();
IGrayIndex in(image);
IGrayImageIter out(iImage);
// instead of doing things in floating point (expensive)
// we shift everything 8 bits to the left
TInt32 fRow = iRect.iTl.iY << 8;
TInt32 fRowIncr = (iRect.Height() << 8) / iSize.iHeight;
TInt32 fColIncr = (iRect.Width() << 8) / iSize.iWidth;
for (; !out.End(); out.NextRow()) {
TInt32 fCol = iRect.iTl.iX * 256;
for (; !out.REnd(); out++) {
TInt32 iCol = fCol >> 8;
TInt32 iRow = fRow >> 8;
TInt32 fracCol = fCol - (iCol << 8); // fracCol is fractional part << 8
TInt32 fracRow = fRow - (iRow << 8); // fracRow is fractional part << 8
TInt32 pix0 = in[iRow][iCol];
TInt32 pix1;
if (iCol+1 < size.Width()) {
pix1 = in[iRow][iCol+1];
} else {
pix1 = pix0;
}
// midRow0 is the actual pixel value midways between the two columns
// in the first row
TInt32 midRow0 = (pix0 * (256-fracCol) + pix1 * fracCol) >> 8;
TInt32 midRow1;
if (iRow+1 < size.Height()) {
pix0 = in[iRow+1][iCol];
if (iCol+1 < size.Width()) {
pix1 = in[iRow+1][iCol+1];
} else {
pix1 = pix0;
}
// midRow1 is the actual pixel value midways between the two
// columns in the second row
midRow1 = (pix0 * (256-fracCol) + pix1 * fracCol) >> 8;
} else {
midRow1 = midRow0;
}
// nPixel is the actual pixel value between midRow0 and midRow1
TInt32 nPixel = (midRow0 * (256-fracRow) + midRow1 * fracRow) >> 8;
out() = (unsigned char) nPixel;
fCol += fColIncr;
}
fRow += fRowIncr;
}
CDebug::ShowImage(iImage);
CleanupStack::PopAndDestroy(); // unlock
ibEmpty = false;
}
bool CRectStretch::Empty() const
{
return ibEmpty;
}
};
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?