Как объединить 2 или более байтовых элемента в массиве в один байтовый элемент - PullRequest
0 голосов
/ 22 февраля 2012

В начале хочу сказать, что я новичок в C #, так что наберитесь терпения :)
У меня есть массив байтов. Один элемент представляет страницу файла PDF. Теперь мне нужно объединить эти массивы в один. Я надеюсь, что этот новый массив покажет две страницы одна над другой. В этом случае:
Page1 (из позиций [0])
Страница2 (из Элементов [1.])

Это хорошая идея? Мне нужно это, чтобы прикрепить PDF как изображения к службам отчетов без использования базы данных. <Ч /> Screen

EDIT:

Вот мой код:

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

Ответы [ 3 ]

4 голосов
/ 22 февраля 2012

Боюсь, это просто не сработает! Массив байтов, который вы видите, представляет собой сериализованную форму объекта PDF, который представляет каждую страницу PDF. Объединение этих двух вместе приведет к массиву байтов, которые нельзя десериализовать в допустимый объект документа PDF.

Чтобы достичь того, что вам требуется, десериализуйте каждый байтовый массив в подходящее PDF-представление, а затем используйте подходящий API для объединения документов.

2 голосов
/ 22 февраля 2012

+ 1 к ответу ColinE.Чтобы реализовать эффект, которого вы хотите достичь, вам нужно использовать стороннюю библиотеку C # PDF.Вы можете найти некоторые ссылки на библиотеки PDF с открытым исходным кодом в ответах на этот вопрос SO или там .

ОБНОВЛЕНИЕ

Что касается вашего кода - чтобы объединить два изображения так, чтобы одно появлялось сразу за другим, вы можете использовать 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);
}
0 голосов
/ 05 декабря 2014

В случае, если кто-то ищет что-то похожее, где вы просто хотите объединить два массива и не заботиться о размерах и прочем:

        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;
        }
...