WPF: объединить изображения в один файл

1

Мое имя Лукас и я узнаем о WPF/С#.

Я хотел бы присоединиться к нескольким изображениям в одном файле, а также к игре с несколькими текстурами, которые находятся в одном файле, но я понятия не имею, как это сделать. Может ли кто-нибудь помочь мне хотя бы подумать, как это сделать?

//Convert Image to Byte[]

    public byte[] getByteFromImage()
        {
            byte[] imageArray = File.ReadAllBytes(op.FileName);
            return imageArray;
        }

//Convert Byte[] to Image

        public void getImageFromByte()
        {
            FileStream f = new FileStream("escudos.bcf", FileMode.Open);
            BinaryReader b = new BinaryReader(f);

            Int64 c = f.Length+1;
            MemoryStream ms = new MemoryStream(b.ReadBytes(int.Parse(c.ToString())));
            Image image = new Image();
            image.Source = BitmapFrame.Create(ms, BitmapCreateOptions.None,
                                      BitmapCacheOption.OnLoad);

            imgPatch2.Source = image.Source;
            f.Dispose();
        }

//Create Binary File

        public void save(byte[] img)
        {
            FileStream f;

            if (!File.Exists("escudos.bcf"))
            {
                f = new FileStream("escudos.bcf", FileMode.Create);
            }

            else
            {
                f = new FileStream("escudos.bcf", FileMode.Append);
            }

            BinaryWriter b = new BinaryWriter(f);
            b.Write(img);
            b.Close();
            f.Dispose();
        }

Я думал, что при этом создайте файл и сохраните его в двоичных изображениях. Пока я не получил эту часть, но поскольку этот файл будет иметь несколько изображений в двоичном формате, я не знаю, как выбрать только одно бинарное изображение.

public void xmlCreate(string name, Int64 ini, Int64 fin)
        {
            if (!File.Exists("Escudos.xml")) 
            {
                XmlTextWriter w = new XmlTextWriter("Escudos.xml", System.Text.Encoding.UTF8);
                w.Formatting = Formatting.Indented;

                w.WriteStartDocument();

                w.WriteStartElement("Time");
                w.WriteStartElement(name);
                w.WriteElementString("Inicio", ini.ToString());
                w.WriteElementString("Fim", fin.ToString());
                w.WriteEndElement();
                w.WriteEndDocument();

                w.Close();
            }

            else
            {


                XDocument doc = XDocument.Load("Escudos.xml");
                doc.Root.Add(new XElement(name));
                doc.Root.Element(name).Add(new XElement("Inicio", ini.ToString()));
                doc.Root.Element(name).Add(new XElement("Fim", fin.ToString()));
                doc.Save("Escudos.xml");


            }
        }

Теперь я создал файл xml для хранения начала и конца байтов. Я могу добавить только тогда, когда я создаю новый XML файл, я не могу получить созданный xml и добавить новые байты. Когда я иду загрузить файл xml, выдается сообщение об ошибке.

"Необработанное исключение типа" System.Xml.XmlException "произошло в System.Xml.dll. Дополнительная информация:"> "- это неожиданный токен. Ожидаемый токен равен '='. Строка 3, позиция 15."


ОБНОВИТЬ

когда я читаю байты для формирования изображения, всегда одинаково, даже добавляя разные изображения. Я добавлю код ниже

//Add Image

private void btAddImage_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog op = new OpenFileDialog();
            op.Title = "Selecione a Imagem";
            op.Filter = "All supported graphics|*.jpg;*.jpeg;*.png|" +
                "JPEG (*.jpg;*.jpeg)|*.jpg;*.jpeg|" +
                "Portable Network Graphic (*.png)|*.png";

            if (op.ShowDialog() == true)
            {
                imgPatch.Source = new BitmapImage(new Uri(op.FileName));
                txtName.Focus();
            }
        }


//Convert Image

 private void btConvertImage_Click(object sender, RoutedEventArgs e)
        {
            if (String.IsNullOrEmpty(txtName.Text))
            {
                txtName.Focus();
                MessageBox.Show("Preencha o Nome", "Error");
            }

            else
            {
                save(ConvertFileToByteArray(op.FileName), txtName.Text);
            }
        }

//Image to Byte Array

private static byte[] ConvertFileToByteArray(String FilePath)
        {
            return File.ReadAllBytes(FilePath);
        }


//Save Binary File and XML File

public void save(byte[] img, string nome)
        {
            FileStream f;
            long ini, fin = img.Length; 

            if (!File.Exists("Escudos.bcf"))
            {
                f = new FileStream("Escudos.bcf", FileMode.Create);
                ini = 0;
            }

            else
            {
                f = new FileStream("Escudos.bcf", FileMode.Append);
                ini = f.Length + 1;
                bin = new TestBinarySegment();

            }

            bin.LoadAddSave("Escudos.xml", "Brasileiro", nome, ini, fin);



            BinaryWriter b = new BinaryWriter(f);
            b.Write(img);
            b.Close();
            f.Dispose();



        }


//Load Image from Byte
private void btLoad_Click(object sender, RoutedEventArgs e)
        {
            getImageFromByte();
        }


//Byte to Image
public void getImageFromByte(int start, int length)
        {
            using (FileStream fs = new FileStream("Escudos.bcf", FileMode.Open))
            {
                byte[] iba = new byte[fs.Length+1];
                fs.Read(iba, start, length);
                Image image = new Image();
                image.Source = BitmapFrame.Create(fs, BitmapCreateOptions.None,
                                          BitmapCacheOption.OnLoad);

                imgPatch2.Source = image.Source;
            }
        }

благодаря

  • 0
    Я вижу проблему, вам нужен файл данных XML для хранения структуры Rect для каждого изображения.
  • 0
    поэтому мне нужно создать файл данных XML для хранения двоичных кодов?
Показать ещё 12 комментариев
Теги:
wpf
image
serialization

1 ответ

1
Лучший ответ

У вас есть двоичный файл, где его содержимое является сегментом, и каждый сегмент содержит двоичную информацию, необходимую для создания изображения. Вам нужно сохранить начальный индекс и длину каждого сегмента, чтобы вы могли его восстановить. Один из способов сделать это - с XML файлом.

Для начала создайте класс контейнера для сегментов. Похоже на это...

public class BinarySegment
{
    private const string FileName = "SegmentData.xml";
    private static XmlSerializer serializer = new XmlSerializer(typeof(List<BinarySegment>));
    public string SegmentName { get; set; }
    public long SegmentStartIndex { get; set; }
    public long SegmentLength { get; set; }
    public static List<BinarySegment> LoadFromFile()
    {
        if (!File.Exists(FileName))
        {
            throw new Exception("File must be created first");
        }
        try
        {
            using (StreamReader sr = new StreamReader(FileName))
            {
                return serializer.Deserialize(sr) as List<BinarySegment>;
            }
        }
        catch
        {
            throw new Exception("File as become corrupted");
        }
    }
    public static void Save(List<BinarySegment> list)
    {
        try
        {
            using (StreamWriter sw = new StreamWriter(FileName))
            {
                serializer.Serialize(sw, list);
            }
        }
        catch
        {
            throw;
        }
    }
}

Для каждого изображения в вашем двоичном файле есть один экземпляр этого класса. Он будет читать/записывать список двоичных разделов.

Чтобы проверить класс, создайте тестовый класс следующим образом...

public class TestBinarySegment
{
    public TestBinarySegment()
    {
        List<BinarySegment> myBinarySegments = new List<BinarySegment>();
        myBinarySegments.Add(new BinarySegment{SegmentName = "Segment1", SegmentStartIndex = 0, SegmentLength = 1111});
        myBinarySegments.Add(new BinarySegment { SegmentName = "Segment2", SegmentStartIndex = 1111, SegmentLength = 1111 });
        myBinarySegments.Add(new BinarySegment { SegmentName = "Segment3", SegmentStartIndex = 2222, SegmentLength = 1111 });
        BinarySegment.Save(myBinarySegments);
    }
    public void LoadAddSave()
    {
        List<BinarySegment> myBinarySegments = BinarySegment.LoadFromFile();
        myBinarySegments.Add(new BinarySegment { SegmentName = "Segment4", SegmentStartIndex = 333330, SegmentLength = 1111 });
        BinarySegment.Save(myBinarySegments);
    }
}

Этот класс показывает, как создать список и сохранить его. Он также показывает, как добавлять новые сегменты и сохранять файл xml.

Когда тест запускается, вы получаете такой файл...

<?xml version="1.0" encoding="utf-8"?>
<ArrayOfBinarySegment xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <BinarySegment>
    <SegmentName>Segment1</SegmentName>
    <SegmentStartIndex>0</SegmentStartIndex>
    <SegmentLength>1111</SegmentLength>
  </BinarySegment>
  <BinarySegment>
    <SegmentName>Segment2</SegmentName>
    <SegmentStartIndex>1111</SegmentStartIndex>
    <SegmentLength>1111</SegmentLength>
  </BinarySegment>
  <BinarySegment>
    <SegmentName>Segment3</SegmentName>
    <SegmentStartIndex>2222</SegmentStartIndex>
    <SegmentLength>1111</SegmentLength>
  </BinarySegment>
  <BinarySegment>
    <SegmentName>Segment4</SegmentName>
    <SegmentStartIndex>333330</SegmentStartIndex>
    <SegmentLength>1111</SegmentLength>
  </BinarySegment>
</ArrayOfBinarySegment>

Чтобы запустить тест, используйте такой код...

        TestBinarySegment test = new TestBinarySegment();
        test.LoadAddSave();

Это показывает, как использовать сериализацию XML для создания файла и добавления к нему новых сегментов. Вам нужно будет протестировать эту концепцию, а затем интегрировать ее в свой проект.

  • 0
    Очень хорошо, я понял и смог применить cdio, спасибо! Но мне интересно, если это возможно, мустар в начале документа «ArrayOfBinarySegment» элемент. Слово BinarySegment переименование можно изменить класс, но что ArrayOf?
  • 0
    Понял, спасибо, сейчас попробую реализовать его часть для разделения байтов сгенерированного файла
Показать ещё 7 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню