Пример #1
0
        /// <summary>
        /// Creates an exact copy of the original bitmap with the same PixelFormat.
        /// </summary>
        /// <param name="bmp">Bitmap object to copy.</param>
        /// <returns>A new bitmap object</returns>
        internal static Bitmap CreateCopyExact(Bitmap bmp)
        {
            //Copy size and geometry
            Bitmap ret = BitmapHelper.CreateBitMap(bmp, bmp.PixelFormat);

            // Lock source bitmap in memory
            BitmapData sourceData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, bmp.PixelFormat);
            // Copy image data to binary array
            int imageSize = sourceData.Stride * sourceData.Height;

            byte[] imageBuffer = new byte[imageSize];
            Marshal.Copy(sourceData.Scan0, imageBuffer, 0, imageSize);
            // Unlock source bitmap
            bmp.UnlockBits(sourceData);

            // Lock destination bitmap in memory
            BitmapData destinationData = ret.LockBits(new Rectangle(0, 0, ret.Width, ret.Height), ImageLockMode.WriteOnly, ret.PixelFormat);

            // Copy binary image data to destination bitmap
            Marshal.Copy(imageBuffer, 0, destinationData.Scan0, imageSize);
            // Unlock destination bitmap
            ret.UnlockBits(destinationData);

            return(ret);
        }
Пример #2
0
        /// <summary>
        /// Creates a new Bitmap with the resolution increased by 2 in the vertical direction using
        /// the indicated method.  Source must be 1bppIndexed.  Source must be a standard Fax size.
        /// </summary>
        /// <param name="bmp">Source Bitmap.</param>
        /// <returns>The new bitmap in 1bppIndexed format.</returns>
        internal static Bitmap ConvertTiffLowToTiffHi(Bitmap bmp)
        {
            PageInfo inf = new PageInfo(bmp);

            if (!inf.IsStandardFaxTiff)
            {
                throw new Exception("Source bitmap must be a standard fax tiff.");
            }
            if (inf.PixelFormat != PixelFormat.Format1bppIndexed)
            {
                throw new Exception("Source bitmap must be 1bpp.");
            }

            //If its already a hi resolution, then copy and return.
            if (inf.VerticalResolution == ImageUtility.FAX_TIF_VER_RES_HI)
            {
                return(BitmapHelper.CreateCopyExact(bmp));
            }

            Bitmap ret = BitmapHelper.CreateBitMap(inf.GetStandardPaperSize, FaxQuality.Fine, PixelFormat.Format1bppIndexed);

            // Lock source bitmap in memory
            BitmapData sourceData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format1bppIndexed);

            // Copy image data to binary array
            int imageSize = sourceData.Stride * sourceData.Height;

            byte[] sourceBuffer = new byte[imageSize];
            Marshal.Copy(sourceData.Scan0, sourceBuffer, 0, imageSize);

            // Unlock source bitmap
            bmp.UnlockBits(sourceData);

            // Lock destination bitmap in memory
            BitmapData destinationData = ret.LockBits(new Rectangle(0, 0, ret.Width, ret.Height), ImageLockMode.WriteOnly, PixelFormat.Format1bppIndexed);

            // Copy image data to binary array
            byte[] destinationBuffer = new byte[imageSize * 2];
            int    destinationIndex  = 0;

            for (int j = 0; j < sourceData.Height; j++)         //For every row
            {
                for (int k = 0; k < 2; k++)                     //Do it twice
                {
                    for (int i = 0; i < sourceData.Stride; i++) //For every element
                    {
                        byte s1 = sourceBuffer[(j) * sourceData.Stride + i];
                        destinationBuffer[destinationIndex] = s1;
                        destinationIndex++;
                    }
                }
            }

            // Copy binary image data to destination bitmap
            Marshal.Copy(destinationBuffer, 0, destinationData.Scan0, destinationBuffer.Length);

            // Unlock destination bitmap
            ret.UnlockBits(destinationData);
            return(ret);
        }
Пример #3
0
        /// <summary>
        /// Creates a new PageImage that contains an empty image (no pixel data) with the
        /// appropriate PixelFormat.  Image size and resolution will be the same as the PageImage.
        /// </summary>
        /// <param name="page">The page image to copy.</param>
        /// <param name="pixelFormat">The new pixel format.</param>
        /// <returns>The new page image.</returns>
        private static PageImage CreateEmptyPageImage(PageImage page, PixelFormat pixelFormat)
        {
            PageImage newpage = new PageImage();

            newpage._sourceBmp = BitmapHelper.CreateBitMap(page.PageInfo.WidthPixels, page.PageInfo.HeightPixels, page.PageInfo.HorizontalResolution, page.PageInfo.VerticalResolution, page.Bitmap.Palette, pixelFormat);
            return(newpage);
        }
Пример #4
0
        /// <summary>
        /// A copy of the original with a 32bpp pixel format.
        /// </summary>
        /// <param name="bmp">Bitmap object to copy.</param>
        /// <returns>A new bitmap object</returns>
        internal static Bitmap CreateCopy32Bit(Bitmap bmp)
        {
            Bitmap   ret = BitmapHelper.CreateBitMap(bmp, PixelFormat.Format32bppArgb);
            Graphics g   = Graphics.FromImage(ret);

            g.DrawImage(bmp, 0F, 0F);
            g.Dispose();

            return(ret);
        }
Пример #5
0
        /// <summary>
        /// Creates a Bitmap that will have the indicated pixel format, size and resolution
        /// </summary>
        /// <param name="paperSize">The required paper size</param>
        /// <param name="faxQuality">The required fax quality</param>
        /// <param name="pixelFormat">The needed pixel format</param>
        /// <returns>The new image with the correct settings.</returns>
        internal static Bitmap CreateBitMap(PaperSize paperSize, FaxQuality faxQuality, ColorPalette palette, PixelFormat pixelFormat)
        {
            Bitmap ret = null;

            switch (paperSize)
            {
            case PaperSize.Legal:
            {
                switch (faxQuality)
                {
                case FaxQuality.Fine:
                {
                    ret =
                        palette == null?CreateBitMap(ImageUtility.FAX_TIF_HOR_PX, ImageUtility.FAX_TIF_VER_PX_LGL_HI, ImageUtility.FAX_TIF_HOR_RES, ImageUtility.FAX_TIF_VER_RES_HI, pixelFormat)
                            : CreateBitMap(ImageUtility.FAX_TIF_HOR_PX, ImageUtility.FAX_TIF_VER_PX_LGL_HI, ImageUtility.FAX_TIF_HOR_RES, ImageUtility.FAX_TIF_VER_RES_HI, palette, pixelFormat);

                    break;
                }

                default:
                {
                    ret = palette == null?CreateBitMap(ImageUtility.FAX_TIF_HOR_PX, ImageUtility.FAX_TIF_VER_PX_LGL_LOW, ImageUtility.FAX_TIF_HOR_RES, ImageUtility.FAX_TIF_VER_RES_LOW, pixelFormat)
                              : CreateBitMap(ImageUtility.FAX_TIF_HOR_PX, ImageUtility.FAX_TIF_VER_PX_LGL_LOW, ImageUtility.FAX_TIF_HOR_RES, ImageUtility.FAX_TIF_VER_RES_LOW, palette, pixelFormat);

                    break;
                }
                }
                break;
            }

            default:
            {
                switch (faxQuality)
                {
                case FaxQuality.Fine:
                {
                    ret = palette == null?BitmapHelper.CreateBitMap(ImageUtility.FAX_TIF_HOR_PX, ImageUtility.FAX_TIF_VER_PX_LTR_HI, ImageUtility.FAX_TIF_HOR_RES, ImageUtility.FAX_TIF_VER_RES_HI, pixelFormat)
                              : CreateBitMap(ImageUtility.FAX_TIF_HOR_PX, ImageUtility.FAX_TIF_VER_PX_LTR_HI, ImageUtility.FAX_TIF_HOR_RES, ImageUtility.FAX_TIF_VER_RES_HI, palette, pixelFormat);

                    break;
                }

                default:
                {
                    ret = palette == null?BitmapHelper.CreateBitMap(ImageUtility.FAX_TIF_HOR_PX, ImageUtility.FAX_TIF_VER_PX_LTR_LOW, ImageUtility.FAX_TIF_HOR_RES, ImageUtility.FAX_TIF_VER_RES_LOW, pixelFormat)
                              : CreateBitMap(ImageUtility.FAX_TIF_HOR_PX, ImageUtility.FAX_TIF_VER_PX_LTR_LOW, ImageUtility.FAX_TIF_HOR_RES, ImageUtility.FAX_TIF_VER_RES_LOW, palette, pixelFormat);

                    break;
                }
                }
                break;
            }
            }
            return(ret);
        }
Пример #6
0
        /// <summary>
        /// Returns a 32bppArgb image that only contains black and white based on the given
        /// threshold.  The new copy is the same size and resolution as the source
        /// </summary>
        /// <param name="bmp">The source bitmap</param>
        /// <param name="threshold">The threshold to use.</param>
        /// <returns>The new Monochrome Bitmap</returns>
        public static Bitmap CreateCopyMonochrome(Bitmap bmp, int threshold)
        {
            // If source and destination are not 32 BPP, ARGB format, then throw error
            if (bmp.PixelFormat != PixelFormat.Format32bppArgb)
            {
                throw new Exception("Conversion to Monochrome requires that the source have PixelFormat.Format32bppArgb.");
            }

            Bitmap ret = BitmapHelper.CreateBitMap(bmp, bmp.PixelFormat);

            // Lock source bitmap in memory
            BitmapData sourceData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);

            // Copy image data to binary array
            int imageSize = sourceData.Stride * sourceData.Height;

            byte[] sourceBuffer = new byte[imageSize];
            Marshal.Copy(sourceData.Scan0, sourceBuffer, 0, imageSize);

            // Unlock source bitmap
            bmp.UnlockBits(sourceData);

            int  pixelTotal       = sourceData.Height * sourceData.Width;
            byte destinationValue = 0;

            // Iterate pixels
            for (int i = 0; i < pixelTotal; i++)
            {
                pixelTotal = sourceBuffer[i * 4 + 1] + sourceBuffer[i * 4 + 2] + sourceBuffer[i * 4 + 3];

                if (pixelTotal > threshold)
                {
                    destinationValue = 255;
                }
                else
                {
                    destinationValue = 0;
                }

                sourceBuffer[i * 4 + 1] = destinationValue;
                sourceBuffer[i * 4 + 2] = destinationValue;
                sourceBuffer[i * 4 + 3] = destinationValue;
            }

            // Lock source bitmap in memory
            BitmapData destinationData = ret.LockBits(new Rectangle(0, 0, ret.Width, ret.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);

            // Copy binary image data to destination bitmap
            Marshal.Copy(sourceBuffer, 0, destinationData.Scan0, imageSize);

            // Unlock destination bitmap
            ret.UnlockBits(destinationData);
            return(ret);
        }
Пример #7
0
        /// <summary>
        /// Creates a copy of the given bitmap after rotation using the supplied intermediate resolution
        /// and Angle.  Positive Angle is Clockwise.  The resulting image has the same horizonatal
        /// and vertical resolution as the given page, but geometry may have changed (height and width).
        /// </summary>
        /// <param name="bmp">The Bitmap to rotate</param>
        /// <param name="intermediateResolution">The intermediate resolution to use.</param>
        /// <param name="rotationAngle">The angle to rotate the image</param>
        /// <returns></returns>
        public static Bitmap CreateCopyRotate(Bitmap bmp, float rotationAngle)
        {
            PageInfo bmpinfo = new PageInfo(bmp);

            PointF[] pts = new PointF[4];
            pts[0] = new PointF(0, 0);
            pts[1] = new PointF(bmpinfo.WidthInches, 0);
            pts[2] = new PointF(0, bmpinfo.HeightInches);
            pts[3] = new PointF(bmpinfo.WidthInches, bmpinfo.HeightInches);

            Matrix mx = new Matrix();

            mx.RotateAt(rotationAngle, new Point(0, 0), MatrixOrder.Append);
            mx.TransformPoints(pts);

            float width;
            float height;
            float dx;
            float dy;

            BitmapHelper.GetExtents(pts, out width, out height, out dx, out dy);

            //If the overall image is bigger than 5000 pixels in either direction, then lets scale it by adjusting the Intermediate resolution - We'll scale it to about 4000 px.
            float intermediateResolution = Math.Max(bmp.VerticalResolution, bmp.HorizontalResolution);

            if (Math.Max(bmpinfo.WidthPixels, bmpinfo.HeightPixels) > 5000)
            {
                intermediateResolution = (float)(int)(4000 / Math.Max(bmpinfo.HeightInches, bmpinfo.WidthInches));
            }

            mx.Translate((int)(dx * intermediateResolution), (int)(dy * intermediateResolution), MatrixOrder.Append);
            //Flip width and height
            Bitmap temp = BitmapHelper.CreateBitMap(width, height, intermediateResolution, intermediateResolution, PixelFormat.Format32bppArgb);
            {
                Graphics g = Graphics.FromImage(temp);
                g.ResetTransform();
                g.Transform = mx;
                g.DrawImage(bmp, new Point(0, 0));
                g.Dispose();
            }
            Bitmap ret = BitmapHelper.CreateBitMap(width, height, bmpinfo.HorizontalResolution, bmpinfo.VerticalResolution, PixelFormat.Format32bppArgb);

            {
                Graphics g = Graphics.FromImage(ret);
                g.ResetTransform();
                g.DrawImage(temp, new Point(0, 0));
                g.Dispose();
            }
            temp.Dispose();

            return(ret);
        }
Пример #8
0
        /// <summary>
        /// Creates a new PageImageList that contains empty images (no pixel data) with the
        /// appropriate PixelFormat, Size and Resolution.
        /// </summary>
        /// <param name="pageCount">Page count to get.</param>
        /// <param name="pixelFormat">The new pixel format.</param>
        /// <param name="quality">The fax quality to use (sets resolution)</param>
        /// <param name="paperSize">The page size to use (width and height)</param>
        /// <returns>The new page image list.</returns>
        private static List <PageImage> CreateEmptyPageImageList(int pageCount, PixelFormat pixelFormat, ColorPalette palette, FaxQuality quality, PaperSize paperSize)
        {
            List <PageImage> ret = new List <PageImage>();

            //Get out if not pages in list.
            if (pageCount <= 0)
            {
                return(ret);
            }

            int   width = ImageUtility.FAX_TIF_HOR_PX;
            float hres  = ImageUtility.FAX_TIF_HOR_RES;

            int   height = 0;
            float vres   = 0.0F;

            if (quality == FaxQuality.Fine)
            {
                vres = ImageUtility.FAX_TIF_VER_RES_HI;
                if (paperSize == PaperSize.Legal)
                {
                    height = ImageUtility.FAX_TIF_VER_PX_LGL_HI;
                }
                else
                {
                    height = ImageUtility.FAX_TIF_VER_PX_LTR_HI;
                }
            }
            else
            {
                vres = ImageUtility.FAX_TIF_VER_RES_LOW;
                if (paperSize == PaperSize.Legal)
                {
                    height = ImageUtility.FAX_TIF_VER_PX_LGL_LOW;
                }
                else
                {
                    height = ImageUtility.FAX_TIF_VER_PX_LTR_LOW;
                }
            }

            for (int i = 0; i < pageCount; i++)
            {
                PageImage newpage = new PageImage();
                newpage._sourceBmp = BitmapHelper.CreateBitMap(width, height, hres, vres, palette, pixelFormat);
                ret.Add(newpage);
            }
            return(ret);
        }
Пример #9
0
        /// <summary>
        /// Creates a padded Fax page.  Source must be 1bpp.  Returned bitmap is 1bpp.
        /// </summary>
        /// <param name="bmp"></param>
        /// <param name="quality"></param>
        /// <param name="paperSize"></param>
        /// <returns></returns>
        public static Bitmap CreateCopyFaxGeometryPadding(Bitmap bmp, FaxQuality quality, PaperSize paperSize)
        {
            PageInfo inf = new PageInfo(bmp);

            if (!(inf.GetStandardFaxQuality == quality))
            {
                throw new Exception("Fax quality must match source.");
            }
            if (!(inf.PixelFormat != PixelFormat.Format1bppIndexed))
            {
                throw new Exception("Source bitmap must have 1bppIndexed format.");
            }

            if (!(inf.GetStandardPaperSize == paperSize))
            {
                return(BitmapHelper.CreateCopyExact(bmp));
            }

            if (inf.GetStandardPaperSize == PaperSize.Legal && paperSize == PaperSize.Letter)
            {
                throw new Exception("Method cannnot reduce Paper size.");
            }

            Bitmap ret = BitmapHelper.CreateBitMap(paperSize, quality, PixelFormat.Format1bppIndexed);

            // Lock source bitmap in memory
            BitmapData sourceData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);

            // Copy image data to binary array
            int imageSize = sourceData.Stride * sourceData.Height;

            byte[] sourceBuffer = new byte[imageSize];
            Marshal.Copy(sourceData.Scan0, sourceBuffer, 0, imageSize);

            // Unlock source bitmap
            bmp.UnlockBits(sourceData);

            // Lock destination bitmap in memory
            BitmapData destinationData = ret.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, PixelFormat.Format1bppIndexed);

            // Copy binary image data to destination bitmap
            Marshal.Copy(sourceBuffer, 0, destinationData.Scan0, imageSize);

            // Unlock destination bitmap
            ret.UnlockBits(destinationData);
            return(ret);
        }
Пример #10
0
        internal static Bitmap Convert8BppTo32Bpp(Bitmap bmp)
        {
            if (bmp.PixelFormat != PixelFormat.Format8bppIndexed)
            {
                throw new Exception("PixelFormat must be Format8bppIndexed.");
            }

            //Grayscale value (0-255) = R = G = B
            //So copy grayscale value to R/G/B bytes, setting A to 255
            BitmapData bmpData   = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed);
            int        imageSize = bmpData.Stride * bmpData.Height;

            byte[] bmpBuffer = new byte[imageSize];
            Marshal.Copy(bmpData.Scan0, bmpBuffer, 0, imageSize);
            bmp.UnlockBits(bmpData);

            Bitmap     destBmp  = BitmapHelper.CreateBitMap(bmp, PixelFormat.Format32bppArgb);
            BitmapData destData = destBmp.LockBits(new Rectangle(0, 0, destBmp.Width, destBmp.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);

            imageSize = destData.Stride * destData.Height;
            byte[] destBuffer = new byte[imageSize];

            Color[] colorArray = new Color[bmp.Palette.Entries.Length];
            for (int i = 0; i < bmp.Palette.Entries.Length; i++)
            {
                colorArray[i] = bmp.Palette.Entries[i];
            }                                                                                                            //Create array of palette for quick lookup below

            for (int y = 0; y < bmp.Height; y++)
            {
                for (int x = 0; x < bmp.Width; x++)
                {
                    destBuffer[y * destData.Stride + (x * 4)]     = colorArray[bmpBuffer[y * bmpData.Stride + x]].B;                     //B //bmpBuffer[y * bmpData.Stride + x];
                    destBuffer[y * destData.Stride + (x * 4) + 1] = colorArray[bmpBuffer[y * bmpData.Stride + x]].G;                     //G //bmpBuffer[y * bmpData.Stride + x];
                    destBuffer[y * destData.Stride + (x * 4) + 2] = colorArray[bmpBuffer[y * bmpData.Stride + x]].R;                     //R //bmpBuffer[y * bmpData.Stride + x];
                    destBuffer[y * destData.Stride + (x * 4) + 3] = colorArray[bmpBuffer[y * bmpData.Stride + x]].A;                     //A //255;
                }
            }

            Marshal.Copy(destBuffer, 0, destData.Scan0, imageSize);
            destBmp.UnlockBits(destData);
            return(destBmp);
        }
Пример #11
0
        /// <summary>
        /// Draws the given Bitmap into a new Bitmap that has the indicated fax geometry. Always returns
        /// 32bpp pixel format.
        /// </summary>
        /// <param name="bmp">The source bitmap.</param>
        /// <param name="quality">The Fax Quality.  Default is Low.</param>
        /// <param name="paperSize">The Paper size.  Default is Auto.</param>
        /// <param name="interpolationMode">The Interpolation mode.  Default is High, but will use the current value in Image Utility, unless defined here. size.</param>
        /// <returns>The new PageImageList (always with 32bpp pixel format)</returns>
        internal static Bitmap CreateCopyFaxGeometry(Bitmap bmp, FaxQuality quality, PaperSize paperSize, InterpolationMode interpolationMode)
        {
            bool   destroytemp = false;
            Bitmap tmp         = null;
            Bitmap ret         = null;

            if (bmp.PixelFormat == PixelFormat.Format8bppIndexed)
            {
                tmp = Convert8BppTo32Bpp(bmp); destroytemp = true;
            }
            else if (bmp.PixelFormat == PixelFormat.Format32bppArgb)
            {
                tmp = bmp;
            }
            else
            {
                tmp = BitmapHelper.CreateCopy32Bit(bmp); destroytemp = true;
            }
            //else if (bmp.PixelFormat != PixelFormat.Format32bppArgb) { tmp = bmp; }
            //else { tmp = BitmapHelper.CreateCopy32Bit(bmp); destroytemp = true; }

            ret = BitmapHelper.CreateBitMap(paperSize, quality, PixelFormat.Format32bppArgb);

            Graphics g = Graphics.FromImage(ret);

            g.InterpolationMode = interpolationMode;
            GraphicsUnit gu = GraphicsUnit.Pixel;

            g.DrawImage(tmp, ret.GetBounds(ref gu), tmp.GetBounds(ref gu), GraphicsUnit.Pixel);
            g.Dispose();
            if (destroytemp)
            {
                tmp.Dispose();
            }
            return(ret);
        }
Пример #12
0
        /// <summary>
        /// Creates a new Bitmap with the resolution reduced by half in the vertical direction using
        /// the indicated method.  Source must be 1bppIndexed.  Source must be a standard Fax size.
        /// </summary>
        /// <param name="bmp">Source Bitmap.</param>
        /// <param name="scaleMethod">The scaling method.</param>
        /// <returns>The new bitmap in 1bppIndexed format.</returns>
        internal static Bitmap ConvertTiffHiToTiffLow(Bitmap bmp, HighToLowScaleMethod scaleMethod)
        {
            PaperSize paperSize = BitmapHelper.GetStandardPaperSize(bmp);

            //If the paper size is not standard then throw error
            if (paperSize == PaperSize.Undefined)
            {
                throw new Exception("Source bitmap returned an incorrect paper size.");
            }

            //If its not in 32bppArgb format then throw error
            if (bmp.PixelFormat != PixelFormat.Format1bppIndexed)
            {
                throw new Exception("Source format must be Format1bppIndexed.");
            }

            //If its already a low resolution, then copy and return.
            if (bmp.VerticalResolution == ImageUtility.FAX_TIF_VER_RES_LOW)
            {
                return(BitmapHelper.CreateCopyExact(bmp));
            }

            //No Scale requested.
            if (scaleMethod == HighToLowScaleMethod.NoScale)
            {
                return(BitmapHelper.CreateCopyExact(bmp));
            }

            //If its in tiff high resolution, then throw error
            if (bmp.VerticalResolution != ImageUtility.FAX_TIF_VER_RES_HI)
            {
                throw new Exception("Source resolution is not FAX_TIF_VER_RES_HI.");
            }

            Bitmap ret = BitmapHelper.CreateBitMap(paperSize, FaxQuality.Normal, PixelFormat.Format1bppIndexed);

            // Lock source bitmap in memory
            BitmapData sourceData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format1bppIndexed);

            // Copy image data to binary array
            int imageSize = sourceData.Stride * sourceData.Height;

            byte[] sourceBuffer = new byte[imageSize];
            Marshal.Copy(sourceData.Scan0, sourceBuffer, 0, imageSize);

            // Unlock source bitmap
            bmp.UnlockBits(sourceData);

            // Lock destination bitmap in memory
            BitmapData destinationData = ret.LockBits(new Rectangle(0, 0, ret.Width, ret.Height), ImageLockMode.WriteOnly, PixelFormat.Format1bppIndexed);

            // Create destination buffer
            imageSize = destinationData.Stride * destinationData.Height;
            byte[] destinationBuffer = new byte[imageSize];

            int nnx_ratio = (int)((sourceData.Stride << 16) / destinationData.Stride) + 1;
            int nny_ratio = (int)((sourceData.Height << 16) / destinationData.Height) + 1;

            int   A, B, C, D, x, y, index, gray;
            float x_ratio = ((float)(sourceData.Stride - 1)) / destinationData.Stride;
            float y_ratio = ((float)(sourceData.Height - 1)) / destinationData.Height;
            float x_diff, y_diff;
            int   offset = 0;

            for (int j = 0; j < destinationData.Height; j++)              //For every row
            {
                for (int i = 0; i < destinationData.Stride; i++)          //For each byte in row
                {
                    byte s1 = sourceBuffer[(j * 2) * destinationData.Stride + i];
                    byte s2 = sourceBuffer[((j * 2) + 1) * destinationData.Stride + i];
                    byte d1 = 0;

                    switch (scaleMethod)
                    {
                    case HighToLowScaleMethod.ORing:
                    {
                        d1 = (byte)(s1 | s2);
                        destinationBuffer[j * destinationData.Stride + i] = d1;
                        break;
                    }

                    case HighToLowScaleMethod.ANDing:
                    {
                        d1 = (byte)(s1 & s2);
                        destinationBuffer[j * destinationData.Stride + i] = d1;
                        break;
                    }

                    case HighToLowScaleMethod.Elimination:
                    {
                        d1 = s1;
                        destinationBuffer[j * destinationData.Stride + i] = d1;
                        break;
                    }

                    case HighToLowScaleMethod.Averaging:
                    {
                        //d1 = (byte)(s1 | s2);
                        //d1 = (byte)(s1 ^ s2);
                        d1 = (byte)((s1 + s2) / 2);
                        //int a1s1 = s1 >> 6 & 3;
                        //int a1s2 = s2 >> 6 & 3;
                        //int a2s1 = s1 >> 4 & 3;
                        //int a2s2 = s2 >> 4 & 3;
                        //int a3s1 = s1 >> 2 & 3;
                        //int a3s2 = s2 >> 2 & 3;
                        //int a4s1 = s1 & 3;
                        //int a4s2 = s2 & 3;
                        //d1 = (byte)(((a1s1 + a1s2) / 2 << 6) + ((a2s1 + a2s2) / 2 << 4) + ((a3s1 + a3s2) / 2 << 2) + ((a4s1 + a4s2) / 2));
                        destinationBuffer[j * destinationData.Stride + i] = d1;
                        break;
                    }

                    case HighToLowScaleMethod.NearestNeighbor:
                    {
                        int x2 = ((i * nnx_ratio) >> 16);
                        int y2 = ((j * nny_ratio) >> 16);

                        destinationBuffer[j * destinationData.Stride + i] = sourceBuffer[(y2 * sourceData.Stride) + x2];
                        break;
                    }

                    case HighToLowScaleMethod.Bilinear:
                    {
                        x      = (int)(x_ratio * i);
                        y      = (int)(y_ratio * j);
                        x_diff = (x_ratio * i) - x;
                        y_diff = (y_ratio * j) - y;
                        index  = y * sourceData.Stride + x;

                        A    = sourceBuffer[index] & 0xff;
                        B    = sourceBuffer[index + 1] & 0xff;
                        C    = sourceBuffer[index + sourceData.Stride] & 0xff;
                        D    = sourceBuffer[index + sourceData.Stride + 1] & 0xff;
                        gray = (int)(
                            A * (1 - x_diff) * (1 - y_diff) + B * (x_diff) * (1 - y_diff) +
                            C * (y_diff) * (1 - x_diff) + D * (x_diff * y_diff)
                            );

                        destinationBuffer[offset++] = (byte)gray;
                        break;
                    }
                    }
                }
            }

            // Copy binary image data to destination bitmap
            Marshal.Copy(destinationBuffer, 0, destinationData.Scan0, imageSize);

            // Unlock destination bitmap
            ret.UnlockBits(destinationData);
            return(ret);
        }
Пример #13
0
        /// <summary>
        /// Creates a copy of the given bitmap after cropping white pixels from top and bottom of image.
        /// Requires a 1bitPerPixel image format, and must be a regular sized fax bitmap (1728 pixels wide).
        /// after rotation using the supplied intermediate resolution
        /// and Angle.  Positive Angle is Clockwise.  The resulting image has the same horizonatal
        /// and vertical resolution as the given page, but geometry may have changed (height and width).
        /// </summary>
        /// <param name="bmp">The Bitmap to rotate</param>
        /// <param name="intermediateResolution">The intermediate resolution to use.</param>
        /// <param name="rotationAngle">The angle to rotate the image</param>
        /// <returns></returns>
        public static Bitmap CreateCopyCrop(Bitmap bmp)
        {
            PageInfo bmpinfo = new PageInfo(bmp);

            if (bmpinfo.WidthPixels != ImageUtility.FAX_TIF_HOR_PX && bmpinfo.HorizontalResolution != ImageUtility.FAX_TIF_HOR_RES)
            {
                throw new Exception("Bitmap is not the correct size for cropping.");
            }

            if (bmp.PixelFormat != PixelFormat.Format1bppIndexed)
            {
                throw new Exception("Bitmap is not the correct pixel format for cropping.");
            }

            // Lock source bitmap in memory
            BitmapData sourceData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format1bppIndexed);

            // Copy image data to binary array
            int imageSize = sourceData.Stride * sourceData.Height;

            byte[] sourceBuffer = new byte[imageSize];
            Marshal.Copy(sourceData.Scan0, sourceBuffer, 0, imageSize);

            // Unlock source bitmap
            bmp.UnlockBits(sourceData);


            int firstDataRow = BitmapHelper.ScanForFirstNonWhiteRow(sourceBuffer, sourceData.Stride, true, false);
            int lastDataRow  = BitmapHelper.ScanForFirstNonWhiteRow(sourceBuffer, sourceData.Stride, false, true);

            int totalRows = lastDataRow - firstDataRow + 1;
            int newHeight = 0;

            var quality = FaxQuality.Undefined;
            var paper   = PaperSize.Undefined;

            if (bmp.VerticalResolution == ImageUtility.FAX_TIF_VER_RES_HI)
            {
                if (totalRows <= ImageUtility.FAX_TIF_VER_PX_LTR_HI)
                {
                    newHeight = ImageUtility.FAX_TIF_VER_PX_LTR_HI; paper = PaperSize.Letter;
                }
                else if (totalRows <= ImageUtility.FAX_TIF_VER_PX_LGL_HI)
                {
                    newHeight = ImageUtility.FAX_TIF_VER_PX_LGL_HI; paper = PaperSize.Legal;
                }
                else
                {
                    newHeight = ImageUtility.FAX_TIF_VER_PX_LGL_HI; paper = PaperSize.Legal;
                }
                quality = FaxQuality.Fine;
            }
            if (bmp.VerticalResolution == ImageUtility.FAX_TIF_VER_RES_LOW)
            {
                if (totalRows <= ImageUtility.FAX_TIF_VER_PX_LTR_LOW)
                {
                    newHeight = ImageUtility.FAX_TIF_VER_PX_LTR_LOW; paper = PaperSize.Letter;
                }
                else if (totalRows <= ImageUtility.FAX_TIF_VER_PX_LGL_LOW)
                {
                    newHeight = ImageUtility.FAX_TIF_VER_PX_LGL_LOW; paper = PaperSize.Legal;
                }
                else
                {
                    newHeight = ImageUtility.FAX_TIF_VER_PX_LGL_LOW; paper = PaperSize.Legal;
                }
                quality = FaxQuality.Normal;
            }

            //Make sure the first data row does not go negative.
            firstDataRow = Math.Max(0, firstDataRow - ((newHeight - totalRows) / 2));
            //Make sure last does not extend out of the original document range.
            lastDataRow = Math.Min(Math.Max(0, bmp.Height - 1), Math.Max(0, firstDataRow + newHeight - 1));
            totalRows   = lastDataRow - firstDataRow + 1;

            var startindex    = firstDataRow * sourceData.Stride;
            var length        = totalRows * sourceData.Stride;
            var croppedBitmap = BitmapHelper.CreateBitMap(paper, quality, PixelFormat.Format1bppIndexed);

            // Lock destination bitmap in memory
            BitmapData destinationData = croppedBitmap.LockBits(new Rectangle(0, 0, croppedBitmap.Width, croppedBitmap.Height), ImageLockMode.WriteOnly, PixelFormat.Format1bppIndexed);

            // Copy binary image data to destination bitmap
            Marshal.Copy(sourceBuffer, startindex, destinationData.Scan0, length);

            // Unlock destination bitmap
            croppedBitmap.UnlockBits(destinationData);

            return(croppedBitmap);
        }
Пример #14
0
        /// <summary>
        /// Reduces the PixelFormat to 1bppIndexed and will use threshold
        /// for color reduction.
        /// </summary>
        /// <param name="bmp">The source bitmap</param>
        /// <param name="threshold">The threshold to use</param>
        /// <returns>A new bitmap.</returns>
        public static Bitmap CreateCopy1BppIndexed(Bitmap bmp, int threshold)
        {
            //If its already in the format we need, make a copy and return.
            if (bmp.PixelFormat == PixelFormat.Format1bppIndexed)
            {
                return(BitmapHelper.CreateCopyExact(bmp));
            }

            //If its not in 32bppArgb format then throw error
            if (bmp.PixelFormat != PixelFormat.Format32bppArgb)
            {
                throw new Exception("Source format must be 32BppArgb.");
            }

            //Destination bitmap
            Bitmap ret = BitmapHelper.CreateBitMap(bmp, PixelFormat.Format1bppIndexed);

            // Lock source bitmap in memory
            BitmapData sourceData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);

            // Copy image data to binary array
            int imageSize = sourceData.Stride * sourceData.Height;

            byte[] sourceBuffer = new byte[imageSize];
            Marshal.Copy(sourceData.Scan0, sourceBuffer, 0, imageSize);

            // Unlock source bitmap
            bmp.UnlockBits(sourceData);

            // Lock destination bitmap in memory
            BitmapData destinationData = ret.LockBits(new Rectangle(0, 0, ret.Width, ret.Height), ImageLockMode.WriteOnly, PixelFormat.Format1bppIndexed);

            // Create destination buffer
            imageSize = destinationData.Stride * destinationData.Height;
            byte[] destinationBuffer = new byte[imageSize];

            int  sourceIndex      = 0;
            int  destinationIndex = 0;
            int  pixelTotal       = 0;
            byte destinationValue = 0;
            int  pixelValue       = 128;
            int  height           = bmp.Height;
            int  width            = bmp.Width;

            // Iterate lines
            for (int y = 0; y < height; y++)
            {
                sourceIndex      = y * sourceData.Stride;
                destinationIndex = y * destinationData.Stride;
                destinationValue = 0;
                pixelValue       = 128;

                // Iterate pixels
                for (int x = 0; x < width; x++)
                {
                    // Compute pixel brightness (i.e. total of Red, Green, and Blue values)
                    pixelTotal = sourceBuffer[sourceIndex + 1] + sourceBuffer[sourceIndex + 2] + sourceBuffer[sourceIndex + 3];
                    if (pixelTotal > threshold)
                    {
                        destinationValue += (byte)pixelValue;
                    }
                    if (pixelValue == 1)
                    {
                        destinationBuffer[destinationIndex] = destinationValue;
                        destinationIndex++;
                        destinationValue = 0;
                        pixelValue       = 128;
                    }
                    else
                    {
                        pixelValue >>= 1;
                    }
                    sourceIndex += 4;
                }
                if (pixelValue != 128)
                {
                    destinationBuffer[destinationIndex] = destinationValue;
                }
            }

            // Copy binary image data to destination bitmap
            Marshal.Copy(destinationBuffer, 0, destinationData.Scan0, imageSize);

            // Unlock destination bitmap
            ret.UnlockBits(destinationData);
            return(ret);
        }
Пример #15
0
 /// <summary>
 /// Creates an empty Bitmap that will have the same size and resolution
 /// of the source bitmap with the indicated pixel format.
 /// </summary>
 /// <param name="bmp">The bitmap to copy.</param>
 /// <param name="pixelFormat">The pixel format</param>
 /// <returns>The new bitmap.</returns>
 internal static Bitmap CreateBitMap(Bitmap bmp, PixelFormat pixelFormat)
 {
     return(ImageHelper.IsIndexedFormat(bmp) ? BitmapHelper.CreateBitMap(bmp.Width, bmp.Height, bmp.HorizontalResolution, bmp.VerticalResolution, bmp.Palette, pixelFormat)
                         : BitmapHelper.CreateBitMap(bmp.Width, bmp.Height, bmp.HorizontalResolution, bmp.VerticalResolution, pixelFormat));
 }