Bildzoom-Algorithmus

Projekthintergrund: Der Blogger hat ein Projekt durchgeführt, um Daten von einer Kamera zu erfassen und dann Videodaten auf dem LCD anzuzeigen. Wenn die Auflösung eines von unserer Kamera erfassten Datenrahmens größer ist als die Auflösung unseres LCD, kann das LCD nicht die gesamten Daten anzeigen Bild, zu diesem Zeitpunkt müssen wir einen solchen Bildrahmen zoomen und ihn dann auf dem LCD anzeigen.

 

In diesem Artikel wird die Interpolationsmethode für die Abtastung des nächsten Nachbarn verwendet, um das Bild zu skalieren. Wenn das Originalbild beispielsweise 100 Punkte hat und Sie zehnmal zoomen möchten, müssen Sie 10 Punkte (Punktnummer) wie 0 10 20 30 verwenden. . . 100 (sonst nichts).

Hier analysieren wir direkt durch das Programm: Erstens verwenden wir  die Eingangsauflösung / Auflösung nach der Kompression   kann einen Skalierungswert k erhalten , k basierend auf diesem Wert , um herauszufinden , was wir auf den ursprünglichen speichern möchten vertikalen und horizontalen Linien . Der Schnittpunkt der horizontalen und vertikalen Linien ist der Punkt, den wir speichern möchten.

/**********************************************************************
 * 函数名称: PicZoom
 * 功能描述: 近邻取样插值方法缩放图片
 *            注意该函数会分配内存来存放缩放后的图片,用完后要用free函数释放掉
 *            "近邻取样插值"的原理请参考网友"lantianyu520"所著的"图像缩放算法"
 * 输入参数: ptOriginPic - 内含原始图片的象素数据
 *            ptBigPic    - 内含缩放后的图片的象素数据
 * 输出参数: 无
 * 返 回 值: 0 - 成功, 其他值 - 失败
 ***********************************************************************/
int PicZoom(PT_PixelDatas ptOriginPic, PT_PixelDatas ptZoomPic)
{
    unsigned long dwDstWidth = ptZoomPic->iWidth;//压缩后分辨率的宽度值
    unsigned long* pdwSrcXTable;
	unsigned long x;
	unsigned long y;
	unsigned long dwSrcY;
	unsigned char *pucDest;
	unsigned char *pucSrc;
	unsigned long dwPixelBytes = ptOriginPic->iBpp/8;

	if (ptOriginPic->iBpp != ptZoomPic->iBpp)
	{
		return -1;
	}

        //pdwSrcXTable数组用来存放要保存的是哪些“竖线”(保存上图红色竖线的位置)
    pdwSrcXTable = malloc(sizeof(unsigned long) * dwDstWidth);
    if (NULL == pdwSrcXTable)
    {
        DBG_PRINTF("malloc error!\n");
        return -1;
    }
        //pdwSrcXTable数组用来存放要保存的是哪些“竖线”(保存上图红色竖线的位置)
    for (x = 0; x < dwDstWidth; x++)//生成表 pdwSrcXTable
    {
        pdwSrcXTable[x]=(x*ptOriginPic->iWidth/ptZoomPic->iWidth);
    }

        //循环“压缩后图片的分辨率的高度”次,也就是开始把要留下的点放进输出buffer了
    for (y = 0; y < ptZoomPic->iHeight; y++)
    {		
        //找出每一次要保存的“横线”	
        dwSrcY = (y * ptOriginPic->iHeight / ptZoomPic->iHeight);

        //目的的起始地址
		pucDest = ptZoomPic->aucPixelDatas + y*ptZoomPic->iLineBytes;
        //源的起始地址(横线的位置是每个点的起始地址,竖线的位置是偏移位置)
		pucSrc  = ptOriginPic->aucPixelDatas + dwSrcY*ptOriginPic->iLineBytes;
		
        //每条横线上有dwDstWidth个点要保存
        for (x = 0; x <dwDstWidth; x++)
        {
            //结合pdwSrcXTable数组找出要保存的点
			 memcpy(pucDest+x*dwPixelBytes, pucSrc+pdwSrcXTable[x]*dwPixelBytes, dwPixelBytes);
        }
    }

    free(pdwSrcXTable);
	return 0;
}

 

 

Veröffentlicht 42 Originalartikel · Gefällt mir 10 · Besucher 10.000+

Ich denke du magst

Origin blog.csdn.net/qq_37659294/article/details/104382032
Empfohlen
Rangfolge