public ByteImage ReplicationScale(int newWidth, int newHeight) { ScaleInfo si = new ScaleInfo(width, height, newWidth, newHeight); byte?[][] newImage = Distribute(si); if(si.IsZooming) { byte? curr = null; int rWidth = newImage.Length; int rHeight = newImage[0].Length; int i = 0, j = 0; for(j = 0; j < rHeight; j++) { curr = null; for(i = 0; i < rWidth; i++) { if(newImage[i][j] != null) //set that as the new color curr = newImage[i][j]; else newImage[i][j] = curr; } } for(i = 0; i < rWidth; i++) { curr = null; for(j = 0; j < rHeight; j++) { if(newImage[i][j] != null) //set that as the new color curr = newImage[i][j]; else newImage[i][j] = curr; } } return new ByteImage(Convert(newImage)); } else if(si.IsShrinking) return new ByteImage(Convert(newImage)); else return this; }
///<summary> /// Creates a new image that is of a new resolution. /// If the resolution is smaller than the current resolution /// then shrink the image ///<summary/> public byte?[][] Distribute(ScaleInfo si) { float wFac = si.WidthScalingFactor; float hFac = si.HeightScalingFactor; byte?[][] result = new byte?[si.ResultWidth][]; for(int i = 0; i < si.ResultWidth; i++) result[i] = new byte?[si.ResultHeight]; if(si.IsZooming) { Console.WriteLine("Scaling Up!"); float iFactor = 0.0f; for(int i = 0; i < width; i++) { float jFactor = 0.0f; for(int j = 0; j < height; j++) { result[(int)Math.Round(iFactor)][(int)Math.Round(jFactor)] = image[i][j]; jFactor += hFac; } iFactor += wFac; } return result; } if(si.IsShrinking) { for(int i = 0; i < si.ResultWidth; i++) { for(int j = 0; j < si.ResultHeight; j++) { //overlay...its an interesting idea int r1 = Math.Min(width - 1, Math.Max(0, (int)Math.Floor(i / wFac))); int r2 = Math.Min(height - 1, Math.Max(0, (int)Math.Floor(j / hFac))); result[i][j] = image[r1][r2]; } } return result; } else return Convert(image); }
public override byte[][] Transform(Hashtable input) { //DateTime start = DateTime.Now; //reseed it if(input == null) return null; byte[][] b = (byte[][])input["image"]; int width = (int)input["width"]; int height = (int)input["height"]; //allowSawtooth = (bool)input["sawtooth"]; bool allowVariance = (bool)input["variance"]; bool allowGauss = (bool)input["gauss"]; ScaleInfo si = new ScaleInfo(b.Length, b[0].Length, width, height); if(si.IsZooming) { //compute k across the entire image int nWidth = si.ResultWidth; int nHeight = si.ResultHeight; //apply the original image values to the given points float w = si.WidthScalingFactor; float h = si.HeightScalingFactor; int w0 = (int)Math.Ceiling(w); int h0 = (int)Math.Ceiling(h); // int w0 = 1; // int h0 = 1; float?[][] newImage = new float?[nWidth][]; float[][] imageF = ToFloatTable(b); byte[][] resultant = new byte[si.ResultWidth][]; float[][] preComputedTable = new float[nWidth][]; int[] scaleX = new int[nWidth]; int[] scaleY = new int[nHeight]; float[] xDiv = new float[nWidth - 1]; Thread t = new Thread(() => UpdateDisplacementTable(b, imageF, preComputedTable, nWidth, nHeight, 4, allowGauss, allowVariance, w, h, scaleX, scaleY, xDiv)); for(int i = 0; i < nWidth; i++) { newImage[i] = new float?[nHeight]; resultant[i] = new byte[nHeight]; preComputedTable[i] = new float[nHeight]; scaleX[i] = (int)((float)i / w); } for(int i = 0; i < nWidth - 1; i++) xDiv[i] = (float)Math.Pow(scaleX[i] - scaleX[i + 1], 2.0f); for(int i = 0; i < nHeight; i++) scaleY[i] = (int)((float)i / h); t.Start(); for(int i = 0; i < nWidth - 3; i+=w0) { int x0 = scaleX[i]; int x1 = scaleX[i + 1]; float[] fx0 = imageF[x0]; float[] fx1 = imageF[x1]; float[] pctX = preComputedTable[i]; for(int j = 0; j < nHeight - 3; j+=h0) { int y0 = scaleY[j]; int y1 = scaleY[j + 1]; //order has been messed up for sometime //should go (x0,y0), (x0,y1), (x1,y1), (x1,y0) float f0 = fx0[y0]; float f1 = fx1[y0]; float f2 = fx1[y1]; float f3 = fx0[y1]; float k = pctX[j]; DivideGrid(resultant, newImage, i, j, w, h, f0, f1, f2, f3, k); } } newImage = null; si = null; imageF = null; //Console.WriteLine("Took {0} seconds", DateTime.Now - start); return resultant; } else { ByteImage image = new ByteImage(b); if(si.IsShrinking) { var _i = image.ReplicationScale(si.ResultWidth, si.ResultHeight); byte[][] target = new byte[_i.Width][]; for(int i = 0; i < _i.Width; i++) { byte[] q = new byte[_i.Height]; for(int j = 0; j < _i.Height; j++) target[i][j] = _i[i,j]; target[i] = q; } image = null; return target; } else return b; } }
public override byte[][] Transform(Hashtable input) { //reseed it if(input == null) return null; rnd = new Random(Guid.NewGuid().ToString().GetHashCode()); byte[][] b = (byte[][])input["image"]; int width = (int)input["width"]; int height = (int)input["height"]; allowSawtooth = (bool)input["sawtooth"]; allowVariance = (bool)input["variance"]; allowGauss = (bool)input["gauss"]; ScaleInfo si = new ScaleInfo(b.Length, b[0].Length, width, height); if(si.IsZooming) { //compute k across the entire image int nWidth = si.ResultWidth; int nHeight = si.ResultHeight; //apply the original image values to the given points float w = si.WidthScalingFactor; float h = si.HeightScalingFactor; float?[][] newImage = new float?[nWidth][]; float[][] displacementTable = new float[nWidth][]; float[][] imageF = ToFloatTable(b); byte[][] resultant = new byte[si.ResultWidth][]; for(int i = 0; i < nWidth; i++) { newImage[i] = new float?[nHeight]; displacementTable[i] = new float[nHeight]; resultant[i] = new byte[nHeight]; } for(int i = 0; i < nWidth - 1; i++) { int x0 = (int)((float)i / w); int x1 = (int)((float)(i + 1) / w); float p0 = (float)Math.Pow(x0 - x1, 2.0f); float[] line0 = imageF[x0]; float[] line1 = imageF[x1]; for(int j = 0; j < nHeight - 1; j++) { int y0 = (int)((float)j / h); int y1 = (int)((float)(j + 1) / h); //order has been messed up for sometime //should go (x0,y0), (x0,y1), (x1,y1), (x1,y0) float f0 = line0[y0]; float f1 = line0[y1]; float f2 = line1[y1]; float f3 = line1[y0]; k = ComputeK(2,i,j,b); displacementTable[i][j] = k; //save the base value //if(k < 1.0f) //{ float gauss = !allowGauss ? (float)rnd.NextDouble() : 1.0f; float var = !allowVariance ? Variance(f0,f1,f2,f3) : 1.0f; float tmp = (float)Math.Sqrt(1.0f - (float)Math.Pow(2.0f, 2.0f * k - 2f)) * DeltaX(p0,y0,y1) * gauss * var; k = tmp; //} DivideGrid(resultant, newImage, i, j, w, h, f0, f1, f2, f3); } } if(allowSawtooth) { List<float> temp = new List<float>(); for(int x = 0; x < si.ResultWidth; x++) { int outCount = 0; int pX = x - 1; bool pXValid = (pX >=0); if(pXValid) outCount++; int fX = x + 1; bool fXValid = (fX < si.ResultWidth); if(fXValid) outCount++; for(int y = 0; y < si.ResultHeight; y++) { if(newImage[x][y] == null || newImage[x][y] > 1.0f) { temp.Clear(); int pY = y - 1; int fY = y + 1; int count = outCount; float v0 = 0f, v1 = 0f, v2 = 0f, v3 = 0f; //f-type computation if(pXValid) { v0 = ((float)newImage[pX][y]); temp.Add(v0); } if(pY >= 0) { v1 = ((float)newImage[x][pY]); temp.Add(v1); count++; } if(fXValid) { v2 = ((float)newImage[fX][y]); temp.Add(v2); } if(fY < si.ResultHeight) { v3 = ((float)newImage[x][fY]); temp.Add(v3); count++; } //if count == 0 then we have bigger problems float total = (1.0f / (float)count); float p0 = total * (v0 + v1 + v2 + v3); float gauss = !allowGauss ? (float)rnd.NextDouble() : 1.0f; //get the k value float dX = DeltaX(pX,fX,pY,fY); float cK = displacementTable[x][y]; float var = !allowVariance ? Variance(temp.ToArray()) : 1.0f; float p1 = (float)Math.Pow(2.0f, -(cK / 2.0f)); float p2 = (float)Math.Sqrt(1.0f - (float)Math.Pow(2.0, 2.0f * cK - 2.0f)); float result = 255.0f * Normalize(p0 + p1 * p2 * dX * gauss * var); resultant[x][y] = (byte)result; } } } temp = null; } newImage = null; displacementTable = null; si = null; rnd = null; imageF = null; return resultant; } else { ByteImage image = new ByteImage(b); if(si.IsShrinking) { var _i = image.ReplicationScale(si.ResultWidth, si.ResultHeight); byte[][] target = new byte[_i.Width][]; for(int i = 0; i < _i.Width; i++) { byte[] q = new byte[_i.Height]; for(int j = 0; j < _i.Height; j++) target[i][j] = _i[i,j]; target[i] = q; } image = null; return target; } else return b; } //we create the new }
public override int[][] TransformImage(Hashtable source) { ArgbImage image = new ArgbImage((int[][])source["image"]); int nWidth = (int)source["width"]; int nHeight = (int)source["height"]; ScaleInfo si = new ScaleInfo(image.Width, image.Height, nWidth, nHeight); int?[][] result = image.Distribute(si); //distribute it across the new image if(si.IsShrinking) return ArgbImage.Convert(result); else if(si.IsZooming) return Interpolate(image.Image, result, si.WidthScalingFactor, si.HeightScalingFactor); else return image.Image; // byte[][] srcImage = (byte[][])source["image"]; // int srcWidth = srcImage.Length; // int srcHeight = srcImage[0].Length; // int rsltWidth = (int)source["width"]; // int rsltHeight = (int)source["height"]; // float srcSize = srcWidth * srcHeight; // float rsltSize = rsltWidth * rsltHeight; // float sWidth = srcWidth; // float sHeight = srcHeight; // float rWidth = rsltWidth; // float rHeight = rsltHeight; // float factor = rsltSize / srcSize; // float wFac = rWidth / sWidth; //width difference factor // float hFac = rHeight / sHeight; //height difference factor // if(factor < 1.0f) // { // //TODO: Improve running time of this code using the // //same method as the other interpolation filters // //shrink the image // //we keep track of the // //we need to shrink it down // byte[][] result2 = new byte[rsltWidth][]; // for(int i = 0; i < result2.Length; i++) // { // var tmp = new byte[rsltHeight]; // for(int j = 0; j < tmp.Length; j++) // { // //overlay...its an interesting idea // int r1 = Math.Min(srcWidth - 1, // Math.Max(0, (int)Math.Floor(i / wFac))); // int r2 = Math.Min(srcHeight - 1, // Math.Max(0, (int)Math.Floor(j / hFac))); // tmp[j] = srcImage[r1][r2]; // } // result2[i] = tmp; // } // return result2; // } // else if(factor > 1.0f) // { // byte?[][] rsltImage = new byte?[rsltWidth][]; // for(int i = 0; i < rsltImage.Length; i++) // rsltImage[i] = new byte?[rsltHeight]; // //setup the image // //zooming works by keeping track of i and j factors that // //grab the factor that is closest to a whole number // float iFactor = 0.0f; // for(int i = 0; i < srcWidth; i++) // { // float jFactor = 0.0f; // for(int j = 0; j < srcHeight; j++) // { // //first map it to the target points in the new image // try // { // rsltImage[(int)Math.Round(iFactor)][(int)Math.Round(jFactor)] = srcImage[i][j]; // } // catch(IndexOutOfRangeException) // { // Console.WriteLine("ERROR: iFactor = {0}, jFactor = {1}", iFactor, jFactor); // } // jFactor += hFac; // } // iFactor += wFac; // } // try // { // return Interpolate(srcImage, rsltImage, wFac, hFac); // } // finally // { // srcImage = null; // rsltImage = null; //clean these up // } // } // else // return srcImage; }