I am trying to conver开发者_StackOverflow中文版t object of type iTextSharp.text.Image back to System.Drawing.Image. Here is a chunk of code that is not working:
System.Drawing.Image img = System.Drawing.Image.FromStream(new MemoryStream(itextImg.RawData));
I could be going about this all wrong, but I won't know unless I consult the experts, and after two hours of fruitless searching online, I am finally posting it myself as a question.
I'm pretty sure that will work occasionally, but will fail in the general case... it depends on what compression filters the image is using.
I believe JPEG image streams are exactly what you'd see in a .jpeg file... but for most (all?) other compression types, the image information (height, width, bits per component, number of components, etc) is vital.
So it'll be possible, but Not Like That.
PS: There's at least one image format that iText cannot decompress, CITTFAXDecode (JBIG2, probably others). In those cases, you'll need some Other Software that will get the raw pixel data out so you can wrap it in a Drawing.Image
.
Yes, I found the solution by rewriting BarcodeQRCode class of ITextSharp and GetImageMethod() as described below:
using System;
using System.Collections.Generic;
using System.Drawing;
using iTextSharp.text;
using iTextSharp.text.pdf.qrcode;
using iTextSharp.text.pdf.codec;
/*
Class rewritted to Convert ByteMatrix to BMP image by rewritting GetImage method
from ITextSharp
author: Luis Claudio Souza
*/
namespace iTextSharp.text.pdf{
/**
* A QRCode implementation based on the zxing code.
* @author Paulo Soares
* @since 5.0.2
*/
public class BarcodeQRCode {
ByteMatrix bm;
/**
* Creates the QR barcode. The barcode is always created with the smallest possible size and is then stretched
* to the width and height given. Set the width and height to 1 to get an unscaled barcode.
* @param content the text to be encoded
* @param width the barcode width
* @param height the barcode height
* @param hints modifiers to change the way the barcode is create. They can be EncodeHintType.ERROR_CORRECTION
* and EncodeHintType.CHARACTER_SET. For EncodeHintType.ERROR_CORRECTION the values can be ErrorCorrectionLevel.L, M, Q, H.
* For EncodeHintType.CHARACTER_SET the values are strings and can be Cp437, Shift_JIS and ISO-8859-1 to ISO-8859-16. The default value is
* ISO-8859-1.
* @throws WriterException
*/
public BarcodeQRCode(String content, int width, int height, IDictionary<EncodeHintType, Object> hints) {
QRCodeWriter qc = new QRCodeWriter();
bm = qc.Encode(content, width, height, hints);
}
private byte[] GetBitMatrix() {
int width = bm.GetWidth();
int height = bm.GetHeight();
int stride = (width + 7) / 8;
byte[] b = new byte[stride * height];
sbyte[][] mt = bm.GetArray();
for (int y = 0; y < height; ++y) {
sbyte[] line = mt[y];
for (int x = 0; x < width; ++x) {
if (line[x] != 0) {
int offset = stride * y + x / 8;
b[offset] |= (byte)(0x80 >> (x % 8));
}
}
}
return b;
}
/** Gets an <CODE>Image</CODE> with the barcode.
* @return the barcode <CODE>Image</CODE>
* @throws BadElementException on error
*/
public void GetImage()
{
sbyte[][] imgNew = bm.GetArray();
Bitmap bmp1 = new Bitmap(bm.GetWidth(), bm.GetHeight());
Graphics g1 = Graphics.FromImage(bmp1);
g1.Clear(Color.White);
for (int i = 0; i <= imgNew.Length - 1; i++)
{
for (int j = 0; j <= imgNew[i].Length - 1; j++)
{
if (imgNew[j][i] == 0)
{
g1.FillRectangle(Brushes.Black, i, j, 1, 1);
}
else
{
g1.FillRectangle(Brushes.White, i, j, 1, 1);
}
}
}
bmp1.Save("D:\\QREncode.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
}
}
}
After that, I used this code to call the method:
var hints = new Dictionary<EncodeHintType, object>();
hints.Add(EncodeHintType.ERROR_CORRECTION, iTextSharp.text.pdf.qrcode.ErrorCorrectionLevel.H);
BarcodeQRCode code = new BarcodeQRCode("98134979213479523874952873", 100, 100, hints);
code.GetImage();
In new GetImage method, you can choose what to do with the bmp class. In this case, it saves a JPEG image file but the method can either return a memorystream to be used by the caller.
精彩评论