/// <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); }
internal PageImage(Bitmap bmp, bool ConvertTo32Bit) { if (ConvertTo32Bit) { this._sourceBmp = BitmapHelper.CreateCopy32Bit(bmp); } else { this._sourceBmp = BitmapHelper.CreateCopyExact(bmp); } }
private static PageImage CreateFaxTiffSlowTrack(PageImage page, PaperSize paperSize, FaxQuality faxQuality, ImageOperationResult result) { PageInfo inf = null; PageImage ret = new PageImage(); Bitmap src = null; Bitmap destroy = null; Trace.WriteLine("SlowTrack: CreateCopyExact...", MODNAME); src = BitmapHelper.CreateCopyExact(page._sourceBmp); Trace.WriteLine("SlowTrack: CreateCopyExact done.", MODNAME); inf = new PageInfo(src); if (inf.GetBestFitRotation != 0) { Trace.WriteLine("SlowTrack: Rotating...", MODNAME); destroy = src; src = BitmapHelper.CreateCopyRotate(src, 90); if (destroy != null) { destroy.Dispose(); destroy = null; } inf = new PageInfo(src); Trace.WriteLine("SlowTrack: Rotating done.", MODNAME); } destroy = src; Trace.WriteLine("SlowTrack: CreateCopyFaxGeometry...", MODNAME); src = BitmapHelper.CreateCopyFaxGeometry(src, faxQuality, paperSize, ImageUtility.InterpolationMode); Trace.WriteLine("SlowTrack: CreateCopyFaxGeometry done.", MODNAME); if (destroy != null) { destroy.Dispose(); destroy = null; } inf = new PageInfo(src); destroy = src; Trace.WriteLine("SlowTrack: CreateCopy1BppIndexed: " + ImageUtility.ConvertTo1BppMethod.ToString() + "...", MODNAME); src = BitmapHelper.CreateCopy1BppIndexed(src); Trace.WriteLine("SlowTrack: CreateCopy1BppIndexed done.", MODNAME); if (destroy != null) { destroy.Dispose(); destroy = null; } inf = new PageInfo(src); ret._pageInfo = null; ret._sourceBmp = src; return(ret); }
/// <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); }
/// <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); }
/// <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); }