快速缩放平铺图像

刚开始实现在symbian上,后来在Brew上再实现了一次。效率不错。不过现在都使用opengles来做了,这种软件的方法只能留给自己做个纪念。

       void drawScaledImage(Image *image, int adx, int ady, int awidth, int aheight, int asx, int asy, int aswidth, int asheight)
{
	int dx = adx;
	int dy = ady;
	int width = awidth;
	int height = aheight;
	int sx = asx;
	int sy = asy;
	int swidth = aswidth;
	int sheight = asheight;

        if (image == NULL || sx >= image->getWidth() || sy >= image->getHeight() || width < = 0 || height <= 0 || sx + swidth <= 0 || sy + sheight<= 0 || swidth <= 0 || sheight <= 0)
                return;
		dx += transX;
		dy += transY;
        if (dx >= clip[0] + clip[2] || dy >= clip[1] + clip[3] || dx + width < = clip[0] || dy + height <= clip[1])
                return;
if ( asx + aswidth > image->getWidth())
swidth= image->getWidth() - asx;
if (asy + asheight > image->getHeight())
sheight = image->getHeight() -asy;
        int zoomlengthy = height + 1;
        int zoomlengthx = width + 1;
		int* tablex = (int*)static_tablex;
		int* tabley = (int*)static_tabley;
        ZoomLine(sx, 0, swidth + sx, zoomlengthx, tablex );
        ZoomLine(sy, 0, sheight + sy, zoomlengthy, tabley );
        int startx = sx;
        int starty = sy;

        int save_dx = dx;
        int save_dy = dy;
        if (sx < 0) {
                startx = 0;
                for (int i = 0; i < zoomlengthx; i++) {
                        if (tablex[i] >= startx) {
                                dx += i;
                                width -= i;
                                break;
                        }
                }
        }
        if (sy < 0) {
                starty = 0;
                for (int i = 0; i < zoomlengthy; i++) {
                        if(tabley[i] >= starty) {
                                dy += i;
                                height -= i;
                                break;
                        }
                }
        }
        int endx = sx + swidth;
        int endy = sy + sheight;
        if (endx > image->getWidth()) {
                endx = image->getWidth();
                for (int i = zoomlengthx - 2; i >= 0; i--) {
                        if (tablex[i] < = endx){
                                if(width > i)
                                width = i;
                                break;
                        }
                }
        }
        if (endy > image->getHeight()) {
                endy = image->getHeight();
                for (int i = zoomlengthy - 2; i >= 0; i--) {
                        if(tabley[i] < = endy) {
                                if( height > i)
                                height = i;
                                break;
                        }
                }
        }

        
        IBitmap *pback = IDISPLAY_GetDestination(m_pDisplay);
        IDIB* pDib = NULL;
        IBITMAP_QueryInterface( pback, AEECLSID_DIB, (void**)&pDib);
        IBITMAP_Release(pback);///*iBack->m_pIDIB*/;
					int startx_dx = dx;
					int starty_dy = dy;
					if (startx_dx < clip[0]) {
						startx = tablex[clip[0] - save_dx];
						width -= clip[0] - startx_dx;
						startx_dx = clip[0];
					}
					if (starty_dy < clip[1]) {
						starty = tabley[clip[1] - save_dy];
						height -= clip[1] - dy;
						starty_dy = clip[1];
					}
					int endx_dx = startx_dx + width;
					if (endx_dx > clip[0] + clip[2]) {
						endx_dx = clip[0] + clip[2];
						endx = tablex[endx_dx - save_dx];
					}
					int endy_dy = starty_dy + height;
					if (endy_dy > clip[1] + clip[3]) {
						endy_dy = clip[1] + clip[3];
						endy = tabley[endy_dy - save_dy];
					}
                unsigned short *psrc = (unsigned short*)((unsigned char*)(image->m_pIDIB->pBmp) + image->m_pIDIB->nPitch * starty /*+ (startx < < 1)*/);
                unsigned short *pdes = (unsigned short*)((unsigned char*)(pDib->pBmp) + pDib->nPitch * starty_dy + (startx_dx < < 1));
                unsigned short *pend = (unsigned short*)((unsigned char*)(image->m_pIDIB->pBmp) + image->m_pIDIB->nPitch * endy + (endx < < 1));
                int srcstep = (image->m_pIDIB->nPitch >> 1);// - (endx - startx);
                int desstep = (pDib->nPitch >> 1) - (endx_dx - startx_dx);
				for (int i = starty_dy; i < endy_dy; i++, psrc += (tabley[i-save_dy] - tabley[i-save_dy-1]) * srcstep, pdes += desstep) {
					for (int j = startx_dx; j < endx_dx; j++, pdes++) {
						if( psrc[tablex[j-save_dx]] != image->m_pIDIB->ncTransparent )
							*pdes = psrc[tablex[j-save_dx]];
					}
				}
        IDIB_Release(pDib);
}
void Graphics::ZoomLine(int aStartX, int aStartY, int aEndX, int aEndY, int *aTable)
{
         int t, distance;
         int x = 0;
         int y = 0;
         int iDeltaX = aEndX - aStartX;
         int iDeltaY = aEndY - aStartY;
         int incx, incy;
         if( iDeltaX > 0 )
		incx = 1;
	else if( iDeltaX == 0 )
		incx = 0;
	else
		incx =  - 1;
	if( iDeltaY > 0 )
		incy = 1;
	else if( iDeltaY == 0 )
		incy = 0;
	else
		incy =  - 1;
	iDeltaX = iDeltaX < 0 ? -iDeltaX : iDeltaX;
	iDeltaY = iDeltaY < 0 ? -iDeltaY : iDeltaY;
	if( iDeltaX > iDeltaY )
		distance = iDeltaX;
	else
		distance = iDeltaY;
	for( t = 0; t < distance; t++ )
	{
		aTable[aStartY] = aStartX;
		x += iDeltaX;
		y += iDeltaY;
		if( x > distance )
			x -= distance, aStartX += incx;
		if( y > distance )
			y -= distance, aStartY += incy;
	}
}
       

发表评论

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据