如何将数组中的 2 个或多个字节项合并为一个字节元素

发布于 2025-01-07 18:30:42 字数 2309 浏览 1 评论 0原文

首先我想说,我是 C# 初学者,所以要有耐心:)
我有字节数组。一项代表 pdf 文件的一页。我现在需要将这些数组合并为一个。我希望这个新数组将显示两页,一层一层地显示。在这种情况下:
第 1 页(来自项目 [0])
Page2(来自 Items[1.])

这是好主意吗?我需要这个来将 pdf 作为图像附加到报告服务而不使用数据库。


Screen

编辑:

这是我的代码:

System.Collections.ArrayList items = new System.Collections.ArrayList();
System.IO.FileStream fs = new System.IO.FileStream("C://1.pdf", System.IO.FileMode.Open, System.IO.FileAccess.Read);
byte[] pdf = new byte[fs.Length];
fs.Read(pdf, 0, (int)fs.Length);

PDFParser.Parse parser = new PDFParser.Parse();
System.Collections.Generic.List<System.Drawing.Image> images = parser.Split(pdf);

object dataByte = null;
for (int i = 0; i < images.Count; i++)
{
    System.IO.MemoryStream ms = new System.IO.MemoryStream();
    images[i].Save(ms, System.Drawing.Imaging.ImageFormat.Png);
    items.Add(ms.ToArray());
}

以及 PDFParser.dll 中的方法:

public class Parse
    {
        public List<Image> Split(byte[] document)
        {
            System.IO.MemoryStream ms = new System.IO.MemoryStream(document);
            Document pdfDoc = new Document(new BinaryReader(ms));
            Page page = null;
            List<Image> returnVal = new List<Image>();

            float resolution = 100;
            float scale = resolution / 72f;

            int bmpW = (int) (scale * pdfDoc.Pages[0].Width);
            int bmpH = (int) (scale * pdfDoc.Pages[0].Height);

            for (int i = 0; i < pdfDoc.Pages.Count; i++)
            {
                page = pdfDoc.Pages[i];
                using (Bitmap bitmap = new Bitmap(bmpW, bmpH))
                {
                    Graphics graphics = Graphics.FromImage(bitmap);
                    graphics.ScaleTransform(scale, scale);
                    graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
                    page.Draw(graphics);
                    returnVal.Add((Image)bitmap.Clone());
                }
            }
            return returnVal;
        }
    }

我使用的第三方程序:
http://www.tallcomponents.com/pdfrasterizer3.aspx

In start I want say, I am beginner in C# so be patient :)
I have array of bytes. One item represent page of pdf file. I need now merge this arrays to one. I hope this new array will show two pages one above other. In this case:

Page1 (from Items[0])
Page2 (from Items[1.])

Its good idea? I need this to attach pdf as images to reporting services wihtout using Database.


Screen

EDIT:

Here is my code:

System.Collections.ArrayList items = new System.Collections.ArrayList();
System.IO.FileStream fs = new System.IO.FileStream("C://1.pdf", System.IO.FileMode.Open, System.IO.FileAccess.Read);
byte[] pdf = new byte[fs.Length];
fs.Read(pdf, 0, (int)fs.Length);

PDFParser.Parse parser = new PDFParser.Parse();
System.Collections.Generic.List<System.Drawing.Image> images = parser.Split(pdf);

object dataByte = null;
for (int i = 0; i < images.Count; i++)
{
    System.IO.MemoryStream ms = new System.IO.MemoryStream();
    images[i].Save(ms, System.Drawing.Imaging.ImageFormat.Png);
    items.Add(ms.ToArray());
}

and method from PDFParser.dll:

public class Parse
    {
        public List<Image> Split(byte[] document)
        {
            System.IO.MemoryStream ms = new System.IO.MemoryStream(document);
            Document pdfDoc = new Document(new BinaryReader(ms));
            Page page = null;
            List<Image> returnVal = new List<Image>();

            float resolution = 100;
            float scale = resolution / 72f;

            int bmpW = (int) (scale * pdfDoc.Pages[0].Width);
            int bmpH = (int) (scale * pdfDoc.Pages[0].Height);

            for (int i = 0; i < pdfDoc.Pages.Count; i++)
            {
                page = pdfDoc.Pages[i];
                using (Bitmap bitmap = new Bitmap(bmpW, bmpH))
                {
                    Graphics graphics = Graphics.FromImage(bitmap);
                    graphics.ScaleTransform(scale, scale);
                    graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
                    page.Draw(graphics);
                    returnVal.Add((Image)bitmap.Clone());
                }
            }
            return returnVal;
        }
    }

3'rd party program what I used:
http://www.tallcomponents.com/pdfrasterizer3.aspx

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

甜味超标? 2025-01-14 18:30:42

恐怕这行不通!您看到的字节数组是代表每个 PDF 页面的 PDF 对象的序列化形式。将这两者合并在一起将产生一个字节数组,该数组无法反序列化为有效的 PDF 文档对象。

为了实现您的需求,请将每个字节数组反序列化为合适的 PDF 表示形式,然后使用合适的 API 将文档合并在一起。

I'm afraid this just isn't going to work! The array of bytes that you see is a serialized form of the PDF object that represents each PDF page. Merging these two together will result in an array of bytes which cannot be de-serialized into a valid PDF document object.

To achieve what you require, deserialize each byte array into a suitable PDF representation, than use a suitable API to merge the documents together.

嘿看小鸭子会跑 2025-01-14 18:30:42

对 ColinE 的回答+1。要实现您想要实现的效果,您需要使用一些第三方 C# PDF 库。您可以在这个问题的答案中找到一些开源 PDF 库的链接< /a> 或那里

更新

至于您的代码 - 合并两个图像,以便一个图像紧接着另一个图像出现,您可以使用 Graphics 类,如下所示:

替换

object dataByte = null;
for (int i = 0; i < images.Count; i++)
{
    System.IO.MemoryStream ms = new System.IO.MemoryStream();
    images[i].Save(ms, System.Drawing.Imaging.ImageFormat.Png);
    items.Add(ms.ToArray());
}

System.IO.MemoryStream ms = new System.IO.MemoryStream();

if (images.Count > 0)
{
    int totalHeight = 0;
    int maxWidth = 0;
    for (int i = 0; i< images.count; i++)
    {
        totalHeight += images[i].Height;
        if (images[i].Width > maxWidth)
        {
            maxWidth = images[i].Width;
        }
    } 
    Image mergedImage = new System.Drawing.Bitmap(maxWidth, totalHeight);
    System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(mergedImage);
    int heightOffset = 0;
    for (int i = 0; i< images.Count; i++)
    {
        g.DrawImage(images[i],new Point(0, heightOffset));
        heightOffset += images[i].Height;
    }
    g.Dispose(); // Mandatory! Graphics is using unmanaged resources so it must be disposed explicitly.
    mergedImage.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
}

+1 to ColinE's answer. To implement the effect you want to achieve you'll need to use some 3rd party C# PDF library. You can find some links to open-source PDF libraries in answers to this SO question or there.

UPDATE

As for your code - to merge two images so one appears right after another you can use Graphics class like this:

Replace

object dataByte = null;
for (int i = 0; i < images.Count; i++)
{
    System.IO.MemoryStream ms = new System.IO.MemoryStream();
    images[i].Save(ms, System.Drawing.Imaging.ImageFormat.Png);
    items.Add(ms.ToArray());
}

with

System.IO.MemoryStream ms = new System.IO.MemoryStream();

if (images.Count > 0)
{
    int totalHeight = 0;
    int maxWidth = 0;
    for (int i = 0; i< images.count; i++)
    {
        totalHeight += images[i].Height;
        if (images[i].Width > maxWidth)
        {
            maxWidth = images[i].Width;
        }
    } 
    Image mergedImage = new System.Drawing.Bitmap(maxWidth, totalHeight);
    System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(mergedImage);
    int heightOffset = 0;
    for (int i = 0; i< images.Count; i++)
    {
        g.DrawImage(images[i],new Point(0, heightOffset));
        heightOffset += images[i].Height;
    }
    g.Dispose(); // Mandatory! Graphics is using unmanaged resources so it must be disposed explicitly.
    mergedImage.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
}
神妖 2025-01-14 18:30:42

如果其他人正在寻找类似的东西,您只想合并两个数组而不关心维度和内容:

        private void LoadImage()
        {
            string src = string.empty;
            byte[] mergedImageData = new byte[0];

            mergedImageData = MergeTwoImageByteArrays(watermarkByteArray, backgroundImageByteArray);
            src = "data:image/png;base64," + Convert.ToBase64String(mergedImageData);
            MyImage.ImageUrl = src;
        }

        private byte[] MergeTwoImageByteArrays(byte[] imageBytes, byte[] imageBaseBytes)
        {
            byte[] mergedImageData = new byte[0];
            using (var msBase = new MemoryStream(imageBaseBytes))
            {
                System.Drawing.Image imgBase = System.Drawing.Image.FromStream(msBase);
                Graphics gBase = Graphics.FromImage(imgBase);
                using (var msInfo = new MemoryStream(imageBytes))
                {
                    System.Drawing.Image imgInfo = System.Drawing.Image.FromStream(msInfo);
                    Graphics gInfo = Graphics.FromImage(imgInfo);
                    gBase.DrawImage(imgInfo, new Point(0, 0));
                    //imgBase.Save(Server.MapPath("_____testImg.png"), ImageFormat.Png);
                    MemoryStream mergedImageStream = new MemoryStream();
                    imgBase.Save(mergedImageStream, ImageFormat.Png);
                    mergedImageData = mergedImageStream.ToArray();
                    mergedImageStream.Close();
                }
            }
            return mergedImageData;
        }

In case someone else is looking for something similar where you just want to merge the two arrays and not care about dimensions and stuff:

        private void LoadImage()
        {
            string src = string.empty;
            byte[] mergedImageData = new byte[0];

            mergedImageData = MergeTwoImageByteArrays(watermarkByteArray, backgroundImageByteArray);
            src = "data:image/png;base64," + Convert.ToBase64String(mergedImageData);
            MyImage.ImageUrl = src;
        }

        private byte[] MergeTwoImageByteArrays(byte[] imageBytes, byte[] imageBaseBytes)
        {
            byte[] mergedImageData = new byte[0];
            using (var msBase = new MemoryStream(imageBaseBytes))
            {
                System.Drawing.Image imgBase = System.Drawing.Image.FromStream(msBase);
                Graphics gBase = Graphics.FromImage(imgBase);
                using (var msInfo = new MemoryStream(imageBytes))
                {
                    System.Drawing.Image imgInfo = System.Drawing.Image.FromStream(msInfo);
                    Graphics gInfo = Graphics.FromImage(imgInfo);
                    gBase.DrawImage(imgInfo, new Point(0, 0));
                    //imgBase.Save(Server.MapPath("_____testImg.png"), ImageFormat.Png);
                    MemoryStream mergedImageStream = new MemoryStream();
                    imgBase.Save(mergedImageStream, ImageFormat.Png);
                    mergedImageData = mergedImageStream.ToArray();
                    mergedImageStream.Close();
                }
            }
            return mergedImageData;
        }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文