Hello,
Sorry for the late reply.
In regards to your two requirements, the first one (1-bit with Group4 compression) can be achieved, but for the second one, there's seems no way to set the jpeg compression at present, however, the 8-bit tiff is available. Moreover, the third parameter in the method "JoinTiffImages", that is the enumeration "EncoderValue", is used to set the compression ratio. Under the enumeration, there are a lot of choices, you could choose accordingly. Below is my code for your reference.
- Code: Select all
private void test_Click(object sender, EventArgs e)
{
PdfDocument document = new PdfDocument();
document.LoadFromFile("test.pdf");
//1. 1-bit (black&white) multi-page tiff with Group4 compression
JoinTiffImages(SaveAs1bitBitmap(document), @"11077BW.tiff", EncoderValue.CompressionCCITT4);
//2. 8-bit (grayscale) multi-page tiff
//JoinTiffImages(ToGrayBitmap(document), @"11077GREY.tiff", EncoderValue.CompressionNone);
}
private System.Drawing.Image[] SaveAs1bitBitmap(PdfDocument document)
{
System.Drawing.Image[] images = new System.Drawing.Image[document.Pages.Count];
for (int i = 0; i < document.Pages.Count; i++)
{
images[i] = document.SaveAsImage(i, PdfImageType.Metafile, 400, 400);
Bitmap image = images[i] as Bitmap;
int width = image.Width;
int height = image.Height;
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
//get (x,y) color
Color color = image.GetPixel(x, y);
//get the corresponding b\w color about the color
int value = (color.R + color.G + color.B) / 3;
//set the new color
image.SetPixel(x, y, Color.FromArgb(value, value, value));
}
}
}
return images;
}
private System.Drawing.Image[] ToGrayBitmap(PdfDocument document)
{
System.Drawing.Image[] images = new System.Drawing.Image[document.Pages.Count];
System.Drawing.Image CrtImg;
for (int i = 0; i < document.Pages.Count; i++)
{
CrtImg = document.SaveAsImage(i, PdfImageType.Metafile, 400, 400);
Bitmap image = CrtImg as Bitmap;
if (image != null)
{
// lock the original memory area
Rectangle rect = new Rectangle(0, 0, image.Width, image.Height);
BitmapData bmpData = image.LockBits(rect, ImageLockMode.ReadOnly,
image.PixelFormat);
// obtain the parameter for images
int width = bmpData.Width;
int height = bmpData.Height;
int stride = bmpData.Stride; // scan the stride
int offset = stride - width * 3; // display the gap between the stride and scan line
IntPtr ptr = bmpData.Scan0; // obtain the memory start position
int scanBytes = stride * height; // use stride to demonstrate the memory size
// two pointers pointing to originial arry and target array
int posScan = 0, posDst = 0;
byte[] rgbValues = new byte[scanBytes]; // distrubute the memory area for target array
Marshal.Copy(ptr, rgbValues, 0, scanBytes); // copy the image data into rgbValues
byte[] grayValues = new byte[width * height];
// calculate the grayValues
for (int j = 0; j < height; j++)
{
for (int k = 0; k < width; k++)
{
double temp = rgbValues[posScan++] * 0.11 +
rgbValues[posScan++] * 0.59 + rgbValues[posScan++] * 0.3;
grayValues[posDst++] = (byte)temp;
}
// skip the unused byte at the end of every image data line, length = stride - width * bytePerPixel
posScan += offset;
}
// unlock the memory
Marshal.Copy(rgbValues, 0, ptr, scanBytes);
image.UnlockBits(bmpData);
// build the 8 bit bitmap
images[i] = BuiltGrayBitmap(grayValues, width, height);
}
else
{
return null;
}
}
return images;
}
private static Bitmap BuiltGrayBitmap(byte[] rawValues, int width, int height)
{
// create a 8 bit gery bitmap and lock the momory area for manipulation
Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format8bppIndexed);
BitmapData bmpData = bitmap.LockBits(new Rectangle(0, 0, width, height),
ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
// calculate the image parameters
int offset = bmpData.Stride - bmpData.Width;
IntPtr ptr = bmpData.Scan0;
int scanBytes = bmpData.Stride * bmpData.Height;
byte[] grayValues = new byte[scanBytes];
// assign the image data
int posSrc = 0, posScan = 0; // Index for rawValues and grayValues
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
grayValues[posScan++] = rawValues[posSrc++];
}
posScan += offset;
}
// unlock the memory
Marshal.Copy(grayValues, 0, ptr, scanBytes);
bitmap.UnlockBits(bmpData);
// change the index table of the generated bitmap to grey
ColorPalette palette;
// get an Palette object of the Format8bppIndexed image format
using (Bitmap bmp = new Bitmap(1, 1, PixelFormat.Format8bppIndexed))
{
palette = bmp.Palette;
}
for (int i = 0; i < 256; i++)
{
palette.Entries[i] = Color.FromArgb(i, i, i);
}
// change the index teable
bitmap.Palette = palette;
return bitmap;
}
public static void JoinTiffImages(System.Drawing.Image[] images, string outFile, EncoderValue compressEncoder)
{
//use the save encoder
System.Drawing.Imaging.Encoder enc = System.Drawing.Imaging.Encoder.SaveFlag;
EncoderParameters ep = new EncoderParameters(2);
ep.Param[0] = new EncoderParameter(enc, (long)EncoderValue.MultiFrame);
ep.Param[1] = new EncoderParameter(System.Drawing.Imaging.Encoder.Compression, (long)compressEncoder);
System.Drawing.Image pages = images[0];
int frame = 0;
ImageCodecInfo info = GetEncoderInfo("image/tiff");
foreach (System.Drawing.Image img in images)
{
if (frame == 0)
{
pages = img;
//save the first frame
pages.Save(outFile, info, ep);
}
else
{
//save the intermediate frames
ep.Param[0] = new EncoderParameter(enc, (long)EncoderValue.FrameDimensionPage);
pages.SaveAdd(img, ep);
}
if (frame == images.Length - 1)
{
//flush and close.
ep.Param[0] = new EncoderParameter(enc, (long)EncoderValue.Flush);
pages.SaveAdd(ep);
}
frame++;
}
}
private static ImageCodecInfo GetEncoderInfo(string mimeType)
{
ImageCodecInfo[] encoders = ImageCodecInfo.GetImageEncoders();
for (int j = 0; j < encoders.Length; j++)
{
if (encoders[j].MimeType == mimeType)
return encoders[j];
}
throw new Exception(mimeType + " mime type not found in ImageCodecInfo");
}
Please do not hesitate to contact us if you need any help.
Sincerely,
Jane
E-iceblue support team