Esempio n. 1
0
 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;
 }
Esempio n. 2
0
 ///<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;
        }