Пример #1
0
        public void CalcNonDivTileAvgRGB(int s)
        {
            int r = 0, g = 0, b = 0;

            if (s != bitmap.Width)
            {
                bitmap = ImageProc.ScaleImage(bitmap, s);
            }
            int size = bitmap.Height * bitmap.Height;

            for (int y = 0; y < bitmap.Height; ++y)
            {
                for (int x = 0; x < bitmap.Height; ++x)
                {
                    r += (int)bitmap.GetPixel(x, y).R;
                    g += (int)bitmap.GetPixel(x, y).G;
                    b += (int)bitmap.GetPixel(x, y).B;
                }
            }
            r /= size;
            g /= size;
            b /= size;

            avg.R = r;
            avg.G = g;
            avg.B = b;
        }
Пример #2
0
        public Bitmap GenerateByNormalMethod(BackgroundWorker worker, Bitmap src, int blockSize, List <Tile> tiles, int tileSize, int version)
        {
            int        v          = (version * 4 + 17) * 2 + 1;
            int        dstSize    = v * tileSize; // Depend on qr version
            double     blockTotal = blockSize * blockSize;
            int        width      = v * blockSize;
            int        height     = width;
            Bitmap     newSrc     = ImageProc.ScaleImage(src, width, height); // scaled src
            Bitmap     dst        = new Bitmap(dstSize, dstSize);             // final result
            List <int> candidates = new List <int>();                         // choosen index of candidate'
            int        currDstH   = 0;
            int        currDstW   = 0;

            for (int y = 0; y < newSrc.Height; y += blockSize)
            {
                //currDstH = 0;
                currDstW = 0;
                //main.wor
                worker.ReportProgress((y * 90) / newSrc.Height + 10);
                for (int x = 0; x < newSrc.Width; x += blockSize)
                {
                    ColorSpace.RGB blockAvg;
                    double         blockAvgR = 0.0f, blockAvgG = 0.0f, blockAvgB = 0.0f;
                    Bitmap         currBlock = new Bitmap(blockSize, blockSize);
                    int            currX = 0, currY = 0;
                    blockAvg.R = blockAvg.G = blockAvg.B = 0;
                    for (int i = y; i < y + blockSize; ++i)
                    {
                        for (int j = x; j < x + blockSize; ++j)
                        {
                            blockAvgR += Convert.ToDouble(newSrc.GetPixel(j, i).R);
                            blockAvgG += Convert.ToDouble(newSrc.GetPixel(j, i).G);
                            blockAvgB += Convert.ToDouble(newSrc.GetPixel(j, i).B);
                            currBlock.SetPixel(currX++, currY, newSrc.GetPixel(j, i));
                        }
                        currY++;
                        currX = 0;
                    }
                    blockAvgR /= blockTotal;
                    blockAvgG /= blockTotal;
                    blockAvgB /= blockTotal;
                    double min = double.MaxValue;
                    double max = double.MinValue;
                    Tile   candiate = null;
                    foreach (Tile tile in tiles)
                    {
                        //if (tile.isSelected)
                        //    continue;
                        double r = Math.Pow(((double)tile.avg.R - blockAvgR), 2);
                        double g = Math.Pow(((double)tile.avg.G - blockAvgG), 2);
                        double b = Math.Pow(((double)tile.avg.B - blockAvgB), 2);
                        double d = Math.Sqrt(r + g + b);
                        if (d < min)
                        {
                            min      = d;
                            candiate = tile;
                        }
                        if (d > max)
                        {
                            max = d;
                        }
                    }
                    //candiate.isSelected = true;
                    #region Replace the block by candiate tile
                    currBlock = ImageProc.ScaleImage(currBlock, tileSize);
                    int    tw = 0, th = 0;
                    double alpha = min / max;
                    double var_B = (double)candiate.avg.B - blockAvgB;
                    double var_G = (double)candiate.avg.G - blockAvgG;
                    double var_R = (double)candiate.avg.R - blockAvgR;
                    for (int h = currDstH; th < tileSize; ++h)
                    {
                        for (int w = currDstW; tw < tileSize; ++w)
                        {
                            // out of range, overflow
                            ColorSpace.RGB rgb;
                            //rgb.R = (int)(Convert.ToDouble(currBlock.GetPixel(tw, th).R) * alpha + (1 - alpha) * Convert.ToDouble(candiate.bitmap.GetPixel(tw, th).R));
                            //rgb.G = (int)(Convert.ToDouble(currBlock.GetPixel(tw, th).G) * alpha + (1 - alpha) * Convert.ToDouble(candiate.bitmap.GetPixel(tw, th).G));
                            //rgb.B = (int)(Convert.ToDouble(currBlock.GetPixel(tw, th).B) * alpha + (1 - alpha) * Convert.ToDouble(candiate.bitmap.GetPixel(tw++, th).B));
                            rgb.R = Convert.ToInt32(Convert.ToDouble(candiate.bitmap.GetPixel(tw, th).R) - var_R);
                            rgb.G = Convert.ToInt32(Convert.ToDouble(candiate.bitmap.GetPixel(tw, th).G) - var_G);
                            rgb.B = Convert.ToInt32(Convert.ToDouble(candiate.bitmap.GetPixel(tw++, th).B) - var_B);
                            rgb.R = ImageProc.NormalizeRGB(rgb.R);
                            rgb.G = ImageProc.NormalizeRGB(rgb.G);
                            rgb.B = ImageProc.NormalizeRGB(rgb.B);

                            Color pixel = Color.FromArgb(255, rgb.R, rgb.G, rgb.B);
                            dst.SetPixel(w, h, pixel);
                        }
                        th++;
                        tw = 0;
                    }
                    currDstW += tileSize;
                    #endregion
                }
                currDstH += tileSize;
            }
            return(dst);
        }