This Image Processing Reference section displays the code for an example program that demonstrates how to calculate a Fourier transform for the color channels of an image.
<?php
function Clamp($iGray) {
if ($iGray < 0) {
return 0;
} elseif ($iGray > 255) {
return 255;
} else {
return $iGray;
}
}
// The sign indicates whether it is a forward (1) or inverse (-1) transform
function FFT($daData, $iLength, $iSign) {
$daSines = new SplFixedArray($iLength+1);
$daCosines = new SplFixedArray($iLength+1);
$iBits = IntVal(round(Log($iLength)/Log(2)));
for ($i = 0; $i < $iLength + 1; ++$i) {
$daSines[$i] = $iSign*sin((3.141592654*$i)/$iLength);
$daCosines[$i] = cos((3.141592654*$i)/$iLength);
}
$iU = 0;
for ($i = 0; $i < $iLength; ++$i) {
$iIndex = 0;
for ($j = 0; $j < $iBits; ++$j) {
$iU = (1<<$j);
$iIndex = (($iIndex<<1) + (($iU&$i)>>$j));
}
$iIndex <<= 1;
$iIndex2 = ($i<<1);
if ($iIndex2 < $iIndex) {
$dTemp = $daData[$iIndex2];
$daData[$iIndex2] = $daData[$iIndex];
$daData[$iIndex] = $dTemp;
$dTemp = $daData[$iIndex2 + 1];
$daData[$iIndex2 + 1] = $daData[$iIndex + 1];
$daData[$iIndex + 1] = $dTemp;
}
}
$iArraySize = ($iLength << 1);
for ($iIncr = 2; $iIncr < $iArraySize; $iIncr <<=1) {
$iStep = ($iIncr << 1);
for ($iU = 0; $iU < $iIncr; $iU += 2) {
$a = ($iU << $iBits);
$iIndex = IntVal(($a - ($a % $iIncr)) / $iIncr);
$dCos = $daCosines[$iIndex];
$dSin = $daSines[$iIndex];
for ($i = $iU; $i < $iArraySize; $i += $iStep) {
$j = $i + $iIncr;
$dTR = $dCos*$daData[$j]-$dSin*$daData[$j+1];
$dTI = $dCos*$daData[$j+1]+$dSin*$daData[$j];
$daData[$j]=$daData[$i]-$dTR;
$daData[$i]=$daData[$i]+$dTR;
$daData[$j+1]=$daData[$i+1]-$dTI;
$daData[$i+1]=$daData[$i+1]+$dTI;
}
}
}
}
function CreateFourierTransformColorChannelsImage($qColorImage) {
$iW = ImageSX($qColorImage);
$iH = ImageSY($qColorImage);
// Allocate the color channel transform images
$qImageR = ImageCreate(256, 256);
$qImageG = ImageCreate(256, 256);
$qImageB = ImageCreate(256, 256);
for ($iC = 0; $iC < 256; ++$iC) {
ImageColorAllocate($qImageR, $iC, 0, 0);
ImageColorAllocate($qImageG, 0, $iC, 0);
ImageColorAllocate($qImageB, 0, 0, $iC);
}
// Create the Red, Green, and Blue Channel images
for ($j = 0; $j < $iH; ++$j) {
for ($i = 0; $i < $iW; ++$i) {
$qColor = ImageColorAt($qColorImage, $i, $j);
$iRed = (($qColor >> 16) & 0xFF);
$iGreen = (($qColor >> 8) & 0xFF);
$iBlue = ($qColor & 0xFF);
ImageSetPixel($qImageR, $i, $j, $iRed);
ImageSetPixel($qImageG, $i, $j, $iGreen);
ImageSetPixel($qImageB, $i, $j, $iBlue);
}
}
$qaChannelImages = array();
$qaChannelImages[0] = $qImageR;
$qaChannelImages[1] = $qImageG;
$qaChannelImages[2] = $qImageB;
$daCmplIm = new SplFixedArray(2*$iW*$iH);
$daComplex = new SplFixedArray(2*$iW);
for ($iImage = 0; $iImage < 3; ++$iImage) {
$qCurrImage = $qaChannelImages[$iImage];
for($i = 0; $i < $iW; ++$i) {
for($j = 0; $j < $iW; ++$j) {
$daCmplIm[2*$i + 2*$iW*$j] = ImageColorAt($qCurrImage, $i, $j);
$daCmplIm[2*$i + 1 + 2*$iW*$j] = 0;
}
}
// Transform the rows
for($iY = 0; $iY < $iW; ++$iY) {
$iR = $iY*($iW << 1);
$iDW = ($iW << 1);
for($iX = 0; $iX < $iDW; ++$iX) {
$daComplex[$iX] = $daCmplIm[$iR + $iX];
}
FFT($daComplex, $iW, 1);
for($iX = 0; $iX < $iDW; ++$iX) {
$daCmplIm[$iR + $iX] = $daComplex[$iX];
}
}
for($iX = 0; $iX < $iDW; $iX +=2) {
for($iY = 0; $iY < $iW; ++$iY) {
$iR = $iY*($iW << 1);
$daComplex[2*$iY] = $daCmplIm[$iR + $iX];
$daComplex[2*$iY + 1] = $daCmplIm[$iR + $iX + 1];
}
FFT($daComplex, $iW, 1);
$dScale = $iW*$iW;
for($iY = 0; $iY < $iW; ++$iY) {
$iR = $iY*($iW << 1);
$daCmplIm[$iR + $iX] = ($daComplex[2*$iY]/$iW);
$daCmplIm[$iR + $iX + 1] = ($daComplex[2*$iY + 1]/$iW);
}
}
// Copy the image data back after the transform
for($i = 0; $i < $iW; ++$i) {
for($j = 0; $j < $iW; ++$j) {
$iCurrPixel = Clamp(IntVal(round(sqrt(
$daCmplIm[2*$i + 2*$iW*$j]*$daCmplIm[2*$i + 2*$iW*$j]
+ $daCmplIm[2*$i + 2*$iW*$j + 1]*$daCmplIm[2*$i + 2*$iW*$j + 1]))));
$iHalfWidth = $iW/2;
$iX = 0;
$iY = 0;
if ($i < $iHalfWidth) {
$iX = $iHalfWidth - $i - 1;
} else {
$iX = $iHalfWidth + $iW - $i - 1;
}
if ($j < $iHalfWidth) {
$iY = $iHalfWidth - $j - 1;
} else {
$iY = $iHalfWidth + $iW - $j - 1;
}
ImageSetPixel($qCurrImage, $iX, $iY, $iCurrPixel);
}
}
}
$qFourierChannelImage = ImageCreateTrueColor(2*$iW, 2*$iH);
// Copy the transformed color channel images
ImageCopyMerge($qFourierChannelImage, $qColorImage, 0, 0, 0, 0, $iW, $iH, 100);
ImageCopyMerge($qFourierChannelImage, $qImageR, $iW, 0, 0, 0, $iW, $iH, 100);
ImageCopyMerge($qFourierChannelImage, $qImageG, $iW, $iH, 0, 0, $iW, $iH, 100);
ImageCopyMerge($qFourierChannelImage, $qImageB, 0, $iH, 0, 0, $iW, $iH, 100);
ImageDestroy($qImageR);
ImageDestroy($qImageG);
ImageDestroy($qImageB);
return $qFourierChannelImage;
}
$qOriginalImage = ImageCreateFromPng("Moses256x256.png");
$qFourierChannelImage = CreateFourierTransformColorChannelsImage($qOriginalImage);
Header('Content-type: image/png');
ImagePng($qFourierChannelImage);
ImageDestroy($qOriginalImage);
ImageDestroy($qFourierChannelImage);
?>
© 20072025 XoaX.net LLC. All rights reserved.