YUV色彩調整
這功能的操作主要是先產生一個可以設定YUV色彩值的畫布(實際上只選擇UV值,Y值預設128),然後根據RGB與YUV的色彩值轉換公式來製作此功能,不過在執行YUV色彩調整時,還需要多一個動作去取得每一個圖片像素的Y值(從RGB值轉Y值)。
RGB與YUV色彩轉換公式,這裡使用整數型態的轉換方法:
根據YUV色彩調整所新增的變數宣告:
BYTE *bPictureImageYUVRow; //產生畫布所使用的變數,
int iR,iG,iB;
int iY,iU,iV;
int iC,iD,iE;
以及新增的TImage元件命名為imgUV,用來產生選取YUV色彩值的畫布。
產生YUV色彩值畫布的程式碼我把它放在開啟圖片的函式裏頭,X軸代表U值、Y軸代表V值,如下:
//YUV色彩值畫布,Y = 128
imgUV->Picture->Bitmap->Height =
256;
imgUV->Picture->Bitmap->Width =
256;
imgUV->Picture->Bitmap->PixelFormat
= pf24bit;
for (i = 0; i < 256; i++)
{
bPictureImageYUVRow
= (Byte*)imgUV->Picture->Bitmap->ScanLine[i];
for
( j = 0; j < 256; j++)
{
iY
= 128;
iU
= j;
iV
= i;
iC
= iY - 16;
iD
= iU - 128;
iE
= iV - 128;
iR
= ( (298 * iC + 409*iE + 128)
>> 8 );
//防止溢位
if
( iR > 255 )
iR = 255;
else
if ( iR < 0 )
iR = 0;
iG
= ( (298*iC - 100*iD - 208*iE + 128) >> 8 );
//防止溢位
if
( iG > 255 )
iG = 255;
else
if ( iG < 0 )
iG = 0;
iB
= ( (298*iC + 516*iD + 128)
>> 8 );
//防止溢位
if
( iB > 255 )
iB = 255;
else
if ( iB < 0 )
iB = 0;
bPictureImageYUVRow[
3 * j + 2 ] = iR;
bPictureImageYUVRow[
3 * j + 1 ] = iG;
bPictureImageYUVRow[
3 * j + 0 ] = iB;
}
}
imgUV->Refresh();
執行YUV色彩調整的函式根據imgUV發生Mouse Down事件時啟用,程式如下:
void __fastcall
TForm1::imgUVMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift,
int X, int Y)
{
iU = X;
iV = Y;
for (i = 0; i < iImageHeight; i++)
{
bPictureImageShowRow
= (Byte*)imgShow->Picture->Bitmap->ScanLine[i];
bPictureImageOriginRow
= (Byte*)imgOrigin->Picture->Bitmap->ScanLine[i];
for
( j =0; j < iImageWidth; j++)
{
bPictureImageShowRow[ 3 * j + 0] =
bPictureImageOriginRow[ 3 * j + 0 ];
bPictureImageShowRow[ 3 * j + 1] =
bPictureImageOriginRow[ 3 * j + 1 ];
bPictureImageShowRow[ 3 * j + 2] =
bPictureImageOriginRow[ 3 * j + 2 ];
iY = ( ( 66 * int(
bPictureImageShowRow[3*j+2] )
+
129 * int( bPictureImageShowRow[3*j+1] )
+ 25 * int( bPictureImageShowRow[3*j+0] ) + 128
) >>8 ) + 16;
iC = iY - 16;
iD = iU - 128;
iE = iV - 128;
iR = ( (298*iC + 409*iE + 128) >> 8 );
//防止溢位
if ( iR > 255 )
iR
= 255;
else if ( iR < 0 )
iR
= 0;
iG = ( (298*iC - 100*iD - 208*iE + 128)
>> 8 );
//防止溢位
if ( iG > 255 )
iG
= 255;
else if ( iG < 0 )
iG
= 0;
iB = ( (298*iC + 516*iD + 128) >> 8 );
//防止溢位
if ( iB > 255 )
iB
= 255;
else if ( iB < 0 )
iB
= 0;
bPictureImageShowRow[3*j+0] = iB;
bPictureImageShowRow[3*j+1] = iG;
bPictureImageShowRow[3*j+2] = iR;
}
}
imgShow->Refresh();
}
部分運行畫面:
可以的話之後想在YUV畫布上產生一個十字記號,用來標示自己剛剛點選的UV值是哪一個。
沒有留言:
張貼留言