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 + -
显示快捷键?