Quantize using an Octree
상속: Quantizer
 public static Bitmap GetThumbnail(int width, int height, string filter, string caption, ImageFormat format, Image b)
 {
     Bitmap source = new Bitmap(b);
     source = new Bitmap(source.GetThumbnailImage(width, height, null, IntPtr.Zero));
     if (format == ImageFormat.Gif)
     {
         source = new OctreeQuantizer(0xff, 8).Quantize(source);
     }
     if ((filter.Length > 0) && filter.ToUpper().StartsWith("SHARPEN"))
     {
         string str = filter.Remove(0, 7).Trim();
         int nWeight = (str.Length > 0) ? Convert.ToInt32(str) : 11;
         BitmapFilter.Sharpen(source, nWeight);
     }
     if (caption.Length <= 0)
     {
         return source;
     }
     using (Graphics graphics = Graphics.FromImage(source))
     {
         StringFormat format2 = new StringFormat();
         format2.Alignment = StringAlignment.Center;
         format2.LineAlignment = StringAlignment.Center;
         using (Font font = new Font("Arial", 12f))
         {
             graphics.TextRenderingHint = TextRenderingHint.AntiAliasGridFit; 
             graphics.FillRectangle(new SolidBrush(Color.FromArgb(150, 0, 0, 0)), 0, source.Height - 20, source.Width, 20);
             graphics.DrawString(caption, font, Brushes.White, 0f, (float)(source.Height - 20));
             return source;
         }
     }
 }
예제 #2
0
        public static void Save(Bitmap B, Stream s, int maxColors)
        {
            OctreeQuantizer quantizer = new OctreeQuantizer(maxColors);

            using (Bitmap bitmap = quantizer.Quantize(B))
            {
                bitmap.Save(s, ImageFormat.Gif);
            }
        }
예제 #3
0
        public static void Save(Bitmap B, Stream s, int maxColors, Color tc)
        {
            OctreeQuantizer quantizer = new OctreeQuantizer(maxColors);

            using (Bitmap bitmap = quantizer.Quantize(B))
            {
                ColorPalette palette = bitmap.Palette;
                for (int i = 0; i < palette.Entries.Length; i++)
                {
                    if (((palette.Entries[i].R == tc.R) && (palette.Entries[i].G == tc.G)) && (palette.Entries[i].B == tc.B))
                    {
                        palette.Entries[i] = Color.FromArgb(0, palette.Entries[i]);
                    }
                }
                bitmap.Palette = palette;
                bitmap.Save(s, ImageFormat.Gif);
            }
        }
예제 #4
0
        // it is used only in desktop sharing (remote control)
        public void captureThreadFuncEx2()
        {
            try
            {
                //int nWidthBlocks=1;
                //int nHeightBlocks = 1;
                //int nBlocks=nHeightBlocks *nWidthBlocks;

                #region  Set window stuff
                // set window stuff
                Win32.USER32.GetWindowRect(sharedWnd, ref rect);

                //SetWindowPos((int)sharedWnd, (int)WindowPlacement.HWD_TOPMOST,rect.Left,rect.Top,
                //					rect.Right-rect.Left, rect.Bottom-rect.Top,0);

                //ShowWindow((IntPtr)sharedWnd, SW_SHOWMAXIMIZED);// new 5 dec

                //SetActiveWindow(sharedWnd);

                //SetForegroundWindow(sharedWnd);
                #endregion

                ImageConverter conv = new ImageConverter();

                #region Create screen bitmap

                // get window dimensions
                blockWidth = (rect.right - rect.left);//nWidthBlocks;
                blockHeight = (rect.bottom - rect.top);//nHeightBlocks;

                hdcSrc = (int)Win32.USER32.GetWindowDC((int)sharedWnd);
                int hdcDest =Win32.USER32.CreateCompatibleDC(hdcSrc);

                // create window bitmap
                int hBitmap = Win32.USER32.CreateCompatibleBitmap(hdcSrc,
                    blockWidth,blockHeight);
                Win32.USER32.SelectObject(hdcDest,hBitmap);

                #endregion

                #region Different initializations
                // get number of adjacent color bits for each pixel
                // in this we will get 4
                int nNumber = Win32.USER32.GetDeviceCaps(hdcSrc,Win32.USER32.BITSPIXEL);

                // calculate buffer size
                int bufferSize= blockWidth*blockHeight*nNumber / 8;

                // initialize buffer
                byte[] buffer = new byte[bufferSize];

                // initialiaze current block number
                //int nBlockNo = 0;

                // clear the hash array.
                //hashArray.Clear();

                // previous hash: this will contain, hash of previously captured blocks
                byte[] prevHash = new byte[blockWidth*blockHeight];

                // b containts a block data
                byte[] blockData=new byte[blockWidth*blockHeight];
                #endregion

                #region STEP1 Send Screen SIZE
                // send window size information
                SendSizeInformation((rect.right - rect.left),
                    (rect.bottom - rect.top));
                #endregion

                // variables to contain cursor position
                Win32.USER32.POINT cursorPosition = new Win32.USER32.POINT();

                Win32.USER32.POINT tempPosition = new Win32.USER32.POINT();
                Win32.USER32.RECT temprect = new Win32.USER32.RECT();

                // screen width and height,
                // these are used later to track whether the window has gone out of the screen or not
                // blocks that are out of screen are not painted or sent
                int _nScreenWidth = Screen.PrimaryScreen.Bounds.Width;
                int _nScreenHeight = Screen.PrimaryScreen.Bounds.Height;

                //int nTemp =0;

                // start coods
                int nStartX = 0,nStartY = 0;

                // current block width and height
                int nCurrentBlockWidth = blockWidth ,nCurrentBlockHeight=blockHeight;

                // hash of the current block
                //	byte[] hash = null;

                int nQuantizeCount=10; // set the quanization count as 10 initially

                //				bt = new StringBuilder(1024);

                //byte[] b;

                // get mouse coordinates
                Point lastMousePoint=new System.Drawing.Point(0,0);

                // create brush
                int _hBrush = Win32.USER32.CreateSolidBrush(0xffffff);

                Win32.USER32.RECT _tempRect = new Win32.USER32.RECT();

                //int nCopyX,  nCopyY;

                // this is not used anywhere so we will comment this coz this isnt used anywhere
                //int hBitmap_dummy = CreateCompatibleBitmap(hdcSrc,blockWidth,blockHeight);

                //bool bDifferenceFound = false;

                OctreeQuantizer quantizer = new OctreeQuantizer(255,8);

                while(m_bActive) // send data only if the window is active
                {
                    try
                    {
                        // whats quantizer count
                        if(nQuantizeCount > 5) // this will be true initially as the quantization count's been set to 10
                        {
                            nQuantizeCount=0; // reinitialize quantizer count
                            quantizer = null;
                            quantizer =new OctreeQuantizer (255,8);
                        }

                        nQuantizeCount++; // increment quantize count

                        /*
                        // get window rect again
                        GetWindowRect(sharedWnd, ref temprect);
                        int tempX= GetScrollPos(sharedWnd, SB_HORZ);
                        int tempY= GetScrollPos(sharedWnd, SB_VERT);
                    */
                        #region check if the window has been resized.
                        /*if(((temprect.Right - temprect.Left) != (rect.Right -rect.Left)) ||
                            ((temprect.Bottom - temprect.Top) != (rect.Bottom - rect.Top)) ||
                            (sPrevWindowText != oldString ) || (iPrev_HorXScroll != tempX) ||
                            (iPrev_VerXScroll != tempY))
                        {
                        #region WINDOW_RESIZED
                            //If the window has been resized
                            bool bRepeatIT = true;

                            while((bRepeatIT) && (m_bActive))
                            {
                                Trace.WriteLine("catptureThread: quantizer while((bRepeatIT) && (m_bActive)) ");
                                try
                                {
                                    rect = temprect;
                                    sPrevWindowText = oldString;
                                    iPrev_HorXScroll = tempX;
                                    iPrev_VerXScroll = tempY;

                                    blockWidth = (rect.Right - rect.Left)/nWidthBlocks;
                                    blockHeight = (rect.Bottom - rect.Top)/nHeightBlocks;

                                    hBitmap = CreateCompatibleBitmap(hdcSrc,blockWidth,blockHeight);
                                    SelectObject(hdcDest,hBitmap);

                                    // not used, not required
                                    //hBitmap_dummy = CreateCompatibleBitmap(hdcSrc,blockWidth,blockHeight);

                                    bufferSize=blockWidth*blockHeight*nNumber/8;//4;
                                    buffer = new byte[bufferSize];

                                    nBlockNo = 0;
                                    hashArray.Clear();
                                    b = null;

                                    b=new byte[blockWidth*blockHeight]; // reinitialize block data

                                    // send size information
                                    SendSizeInformation((rect.Right - rect.Left),
                                        (rect.Bottom - rect.Top));
                                    bRepeatIT = false;

                                }
                                catch(Exception )
                                {

                                    bRepeatIT = true;

                                }
                            }
                        #endregion
                        }
                        else if((temprect.Left != rect.Left) || (temprect.Top != rect.Top)  )
                        {
                        #region Window_Moved
                            //if the window has been moved
                            rect = temprect;

                        #endregion

                        }*/
                        #endregion

                        //nBlockNo = 0;

                        //for(int nRow = 0 ; nRow < nHeightBlocks ; nRow++)
                    {
                        // for each block
                        //for(int nColumn=0; nColumn< nWidthBlocks; nColumn++,nBlockNo++)
                    {
                        try
                        {
                            #region divided into blocks
                            /*
                                    // get start coods
                                    nStartX = nColumn * blockWidth;
                                    nStartY = nRow * blockHeight;

                                    // get block width
                                    nCurrentBlockWidth = blockWidth;
                                    nCurrentBlockHeight = blockHeight;

                                    //Tricking missing pisxels.
                                    // check if its the last column
                                    if(nColumn == (nWidthBlocks -1))
                                    {
                                        // if its the last column, append the remaining
                                        // bits with the rest of the stuff
                                        nTemp = nStartX + blockWidth;
                                        if(nTemp < (rect.Right - rect.Left))
                                            nCurrentBlockWidth += (rect.Right - rect.Left) - nTemp;

                                    }

                                    // if it's the last row
                                    if(nRow == (nHeightBlocks-1))
                                    {
                                        // increate the height
                                        nTemp = nStartY + blockHeight;

                                    }
                                    */
                            #endregion
                            #region BUILD_BITMAP
                            // build the bitmap

                            Win32.USER32.SelectObject(hdcDest,hBitmap);
                            /*
                                     * nCopyX = nCurrentBlockWidth;
                                    nCopyY = nCurrentBlockHeight;

                                    _tempRect.Left = 0;
                                    _tempRect.Top = 0;
                                    _tempRect.Right = nCurrentBlockWidth;
                                    _tempRect.Bottom = nCurrentBlockHeight;
                                    //								int startX=0;
                                    //								int startY=0;
                                    int endX=nCurrentBlockWidth;
                                    int endY=nCurrentBlockHeight;

                                    if(nCurrentBlockWidth + nStartX + temprect.Left > _nScreenWidth)
                                    {
                                        FillRect((IntPtr)hdcDest,ref _tempRect,(IntPtr)_hBrush);
                                        endX=(_nScreenWidth - nStartX- temprect.Left) % nCurrentBlockWidth;
                                        if(endX==0)
                                            endX=nCurrentBlockWidth;
                                    }
                                    else if(nStartX + temprect.Left < 0)
                                    {
                                        FillRect((IntPtr)hdcDest,ref _tempRect,(IntPtr)_hBrush);
                                        //startX=tempRect.Left;
                                    }
                                    else if(nCurrentBlockHeight + nStartY + temprect.Top > _nScreenHeight)
                                    {
                                        FillRect((IntPtr)hdcDest,ref _tempRect,(IntPtr)_hBrush);
                                        endY=(_nScreenHeight - nStartY- temprect.Top) % nCurrentBlockHeight;
                                        if(endY==0)
                                            endY=nCurrentBlockWidth;
                                    }
                                    else if(nStartY + temprect.Top < 0)
                                    {
                                        FillRect((IntPtr)hdcDest,ref _tempRect,(IntPtr)_hBrush);
                                    }
                                    */
                            /*BitBlt(hdcDest,0,0,endX,endY,
                                        hdcSrc,	nStartX,nStartY,
                                        0x00CC0020);
                                        */
                            Win32.USER32.BitBlt(hdcDest,0,0,blockWidth,blockHeight,
                                hdcSrc,	0,0,
                                0x00CC0020);

                            //GetBitmapBits((IntPtr)hBitmap,buffer.Length,buffer);

                            Image _image = Image.FromHbitmap((IntPtr)hBitmap);
                            using( Image _quantized = quantizer.Quantize(_image))
                            {
                                buffer =(byte[]) conv.ConvertTo(_quantized, typeof(byte[]));
                                //buffer = (byte[]) conv.ConvertTo(_image , typeof(byte[]));
                            }

                            _image.Dispose();

                            #endregion
                            #region hashing method
                            //Compute a hash for each image
                            SHA256Managed shaM = new SHA256Managed();
                            byte[] hash1 = shaM.ComputeHash(buffer);
                            byte[] hash2 = shaM.ComputeHash(prevHash );

                            //Compare the hash values
                            for (int i = 0; i < hash1.Length && i < hash2.Length  ; i++)
                            {
                                if (hash1[i] != hash2[i])
                                {								// image has changed
                                    Console.WriteLine(" new image has sent using hash  :  " + DateTime.Now.ToString()+ " " +DateTime.Now.Millisecond.ToString());
                                    int length2=buffer.Length;

                                    /*Image _image = Image.FromHbitmap((IntPtr)hBitmap);
                                            Image _quantized = quantizer.Quantize(_image);
                                            _image.Dispose();

                                            // convert quantized array to byte array
                                            b=(byte[]) conv.ConvertTo(_quantized, typeof(byte[]));
                                            length2 = b.Length;
                                            */
                                    // send image
                                    // note that image was added in the hash array list and
                                    // this data is sent,
                                    CompressAndSendBuffer(ref buffer,DataType.PictureBlock,
                                        ref nStartX,ref nStartY,ref nCurrentBlockWidth,
                                        ref nCurrentBlockHeight, ref length2);
                                    //_quantized.Dispose();
                                    prevHash = (byte[])buffer.Clone();
                                    break;
                                }
                            }

                            #endregion

                            /*int length2=buffer.Length;
                                    Image _image = Image.FromHbitmap((IntPtr)hBitmap);
                                    Image _quantized = quantizer.Quantize(_image);
                                    _image.Dispose();

                                    // convert quantized array to byte array
                                    b=(byte[]) conv.ConvertTo(_quantized, typeof(byte[]));
                                    length2 = b.Length;

                                    // send image
                                    // note that image was added in the hash array list and
                                    // this data is sent,
                                    CompressAndSendBuffer(ref b,DataType.PictureBlock,
                                        ref nStartX,ref nStartY,ref nCurrentBlockWidth,
                                        ref nCurrentBlockHeight,ref length2);

                                    _quantized.Dispose();*/

                        }
                        catch(Exception ex)
                        {
                            WebMeeting.Client.ClientUI.getInstance().ShowExceptionMessage("Module ::: AppShare public void captureThreadFuncEx2()",ex,"",false);
                        }
                    }
                        Thread.Sleep(500);
                    }

                    }
                    catch(Exception ex)
                    {
                        WebMeeting.Client.ClientUI.getInstance().ShowExceptionMessage("Module ::: AppShare public void captureThreadFuncEx2()",ex,"",false);
                    }
                }
            }
            catch(Exception ex)
            {
                WebMeeting.Client.ClientUI.getInstance().ShowExceptionMessage("Module ::: AppShare public void captureThreadFuncEx2()",ex,"",false);
            }
        }
예제 #5
0
        /*run in the case of the App sharing*/
        public void captureThreadFuncEx()
        {
            try
            {
                int nBlocks=nHeightBlocks *nWidthBlocks;
                /*
                 * Intialize Mouse Relevant Stuff
                 */
                IntializeMouseCoordinates();
                /*s
                 * set windows relevant stuff,like get its rectangle,its title,activate it etc..
                 * for more detail go to method header
                 */
                SetWindowStuff();
                /*
                 * initialize imageconverter object
                 * this will be used to convert image into byte array
                 */
                conv=new ImageConverter();
                /*
                 * create window bitmap sturcture on the shared window architecture
                 */
                CreateBitmapStructureForSharedWindow();
                /*
                 * initialize the buffer
                 */
                Initialize_buffer();
                /*
                 * send picture size
                 */
                SendSizeInformation(blockWidth,blockHeight);

                // variables to contain cursor position
                Win32.USER32.POINT cursorPosition = new Win32.USER32.POINT();

                Win32.USER32.RECT temprect = new Win32.USER32.RECT();

                // screen width and height,
                // these are used later to track whether the window has gone out of the screen or not
                // blocks that are out of screen are not painted or sent
                int _nScreenWidth = Screen.PrimaryScreen.Bounds.Width;
                int _nScreenHeight = Screen.PrimaryScreen.Bounds.Height;

                //int nTemp =0;

                // start coods
                int nStartX = 0,nStartY = 0;

                // current block width and height
                //int nCurrentBlockWidth = 0,nCurrentBlockHeight=0;

                // hash of the current block
                //byte[] hash = null;

                //int nQuantizeCount=10; // set the quanization count as 10 initially

                bt = new StringBuilder(1024);

                byte[] b;

                //PitchBlack = 0xffffff

                // create brush
                int _hBrush = Win32.USER32.CreateSolidBrush(0xffffff);

                Win32.USER32.RECT _tempRect = new Win32.USER32.RECT();

                //				int nCopyX,  nCopyY;

                // this is not used anywhere so we will comment this coz this isnt used anywhere
                //int hBitmap_dummy = CreateCompatibleBitmap(hdcSrc,blockWidth,blockHeight);

                //			int nBlockNo = 0;

                OctreeQuantizer quantizer = new OctreeQuantizer(255,8);

                // When u close App share it becomes  false
                // else it remain true uptill the App share is true

                while(m_bActive) // send data only if the window is active
                {
                    try
                    {
                        /*
                         * check window exist if not found then close app share process
                         */
                        if(!bCloseAppshare())
                        {
                            break;
                        }

                        /*
                         * check working window is not shared  then flush and continue
                         */

                        //Zaeem Addition

                        // In previous case thte Sleep was not added here , so that
                        //when it reaches the continue statement, it will skip all the next statement including the
                        // for loop , so that no Sleep in the way , which makes the processing very high
                        // Yet an other Stupid piece of code
                        // Another Check which zaeem is Adding is if the current tab is Appsharing then the image shd be send and same for receiving

                        Thread.Sleep(2000);
                        if(bFlashWindow())
                        {
                            continue;
                        }

                        quantizer =new OctreeQuantizer (255,8);

                        // get server full bitmap
                        if(staticImage!=null)
                        {
                            staticImage.Dispose();
                            staticImage=null;
                        }
                        staticImage= GetServerFullBitmap();
                        /*
                         * this function check last and current coordinate then check
                         * the window coordinate
                         */

                        SendMouseMovements();

                        // If window is inactive then we flush it
                        //
                        //						if(bFlashWindow())
                        //						{
                        //							continue;
                        //							/*
                        //									again return to while loop skip all next instruction in a while
                        //									block.
                        //								*/
                        //						}

                        int length2;//=buffer_CaptureThread.Length;
                        Image _quantized;
                        if(this.staticImage!=null)
                        {
                            _quantized = quantizer.Quantize(staticImage);
                        }
                        else
                            continue;

                        // convert quantized array to byte array
                        b=null;
                        b=(byte[]) conv.ConvertTo(_quantized, typeof(byte[]));

                        length2 = b.Length;

                        // send image
                        // note that image was added in the hash array list and
                        // this data is sent,
                        CompressAndSendBuffer(ref b,DataType.PictureBlock,
                            ref nStartX,ref nStartY,ref this.width_Bitmap,
                            ref this.height_Bitmap,ref length2);
                        SendDummyMouseMovements();
                        _quantized.Dispose();

                        Thread.Sleep(2000);
                    }
                    catch(Exception ex)
                    {
                        WebMeeting.Client.ClientUI.getInstance().ShowExceptionMessage("Module ::: AppShare public void captureThreadFuncEx()",ex,"",false);
                    }
                }

            }
            catch(Exception ex)
            {
                WebMeeting.Client.ClientUI.getInstance().ShowExceptionMessage("Module ::: AppShare public void captureThreadFuncEx()",ex,"",false);
            }
        }