растровое изображение не сохраняет изображение в поток памяти

Нужна небольшая помощь здесь. У меня есть приложение, которое я создаю, которое объединяет две картинки вместе. Проблема в том, что я пытаюсь преобразовать растровое изображение в растровое изображение, чтобы отобразить результат на экране. насколько я могу судить, изображение не сохраняется в потоке памяти в "NwImg.Save(memory,ImageFormat.Jpeg);" Любые идеи??

 //The Code   
    //bitmap to bitmapimage conversion
            using (MemoryStream memory = new MemoryStream())
            {//NwImg is type Bitmap, and at this point i checked properties and values did copy over from the merging
                NwImg.Save(memory, ImageFormat.Jpeg);//here image NwImg.save is suppose to transfer to memory
                memory.Position = 0;
                Nwbi.StreamSource = memory;//memory stream is showing null
                Nwbi.CacheOption = BitmapCacheOption.OnLoad;

            }

Я не знаю, имеет ли это значение, но NwImg представляет собой растровое изображение, созданное путем слияния изображения png поверх jpeg. Я не читал ничего, что говорило бы о том, что это имеет значение, но я решил, что пройду через это.

/// вот весь код по запросу david //Main c#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Drawing;
using System.IO;
using System.Drawing.Imaging;


namespace PicMerger2
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        Pic currentPic = new Pic();
        BitmapImage bi = new BitmapImage(new Uri("\\original photo.jpg"));
        BitmapImage Nwbi = new BitmapImage();
        public MainWindow()
        {
            InitializeComponent();

            OriginalPhoto.Source = bi;
            ResultPhoto.Source = Nwbi;

        }

        private void apply_Click(object sender, RoutedEventArgs e)
        {
            Bitmap NwImg;
            //bitmapimage to bitmap conversion
            using (MemoryStream outStream = new MemoryStream())
            {
                BitmapEncoder enc = new BmpBitmapEncoder();
                enc.Frames.Add(BitmapFrame.Create(bi));
                enc.Save(outStream);
                System.Drawing.Bitmap MarkThisPic = new System.Drawing.Bitmap(outStream);

                // return bitmap; <-- leads to problems, stream is closed/closing ...
                NwImg = new Bitmap(MarkThisPic);
            }
            NwImg = currentPic.MergerTheseTwo(NwImg);


            //bitmap to bitmapimage conversion
            using (MemoryStream memory = new MemoryStream())
            {
                NwImg.Save(memory, ImageFormat.Jpeg);
                memory.Position = 0;
                Nwbi.StreamSource = memory;
                Nwbi.CacheOption = BitmapCacheOption.OnLoad;

            }
            ResultPhoto.Source = Nwbi;
        }
    }
}

//Основной xaml

<Window x:Class="PicMerger2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid HorizontalAlignment="Center">
        <StackPanel Orientation="Horizontal">
            <StackPanel>
                <Image x:Name="OriginalPhoto" Height="200" Stretch="UniformToFill" Source="{Binding}"></Image>
                <Label>Original Images</Label>
            </StackPanel>
            <Button x:Name="apply" Click="apply_Click" Height="25" >Apply Watermark</Button>
            <StackPanel>
                <Image x:Name="ResultPhoto" Height="200" Stretch="UniformToFill" Source="{Binding}"></Image>
                <Label>Watermarked Image</Label>
            </StackPanel>
        </StackPanel>
    </Grid>
</Window>

// класс изображения

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;

namespace PicMerger2
{
    class Pic
    {
        Bitmap Watermark = new Bitmap(PicMerger2.Properties.Resources._Watermark);


        public Bitmap MergerTheseTwo(Bitmap BottomImage)
        {
            try
            {
                using (var canvas = Graphics.FromImage(BottomImage))
                {
                    canvas.InterpolationMode = InterpolationMode.HighQualityBicubic;
                    //       canvas.DrawImage(BottomImage, new Rectangle(0, 0, BottomImage.Width, BottomImage.Height), new Rectangle(0, 0, BottomImage.Width, BottomImage.Height), GraphicsUnit.Pixel);
                    canvas.DrawImage(Watermark, 0, 0);
                    canvas.Save();

                    //Save to current picture
                    Bitmap NewImage = new Bitmap(BottomImage.Width, BottomImage.Height, canvas);
                    return NewImage;
                }
            }
            catch (Exception)
            {

                throw;
            }
        }
    }
}

person chris    schedule 17.07.2013    source источник
comment
Можете ли вы опубликовать код, который объединяет изображения?   -  person David -    schedule 18.07.2013
comment
В вашем apply_Click вы не перематываете outStream до того, как создадите из него растровое изображение. Это может быть проблемой. Кроме того, я подозреваю, что если вы поместите строку ResultPhoto.Source = Nwbi; внутри предыдущего блока using, все начнет работать. Просто предположение. Я думаю, что поток памяти удаляется до того, как изображение будет фактически загружено из него.   -  person Jim Mischel    schedule 18.07.2013
comment
Эй, Джим, что такое «перемотка назад»? Посмотрел класс memorystream на msdn и ничего не нашел о перемотке назад msdn.microsoft.com/en-us/library/system.io.memorystream.aspx также я отслеживал значения при отладке, и проблема заключается в операторе использования, см. первый блок кода выше.   -  person chris    schedule 18.07.2013
comment
перемотка означает возврат к началу файла. Установка позиции на 0. Это был распространенный термин, когда память компьютера была на ленте, и для поиска начала файла требовалось перемотать ленту. Это как-то застряло. Или, может быть, оно окончательно исчезло из лексикона.   -  person Jim Mischel    schedule 18.07.2013
comment
Что означает поток памяти, показывающий нуль? Вы хотите сказать, что если вы проверите переменную memory, она покажет null? Это кажется... крайне маловероятным. Пожалуйста, объясни.   -  person Jim Mischel    schedule 18.07.2013
comment
Пожалуйста, не стесняйтесь попробовать код, я просто переместил строку ResultPhoto.Source = Nwbi; внутри оператора using, но он все еще не отображается.   -  person chris    schedule 18.07.2013


Ответы (2)


Вам нужно будет изменить пару вещей, чтобы ваш код мог работать.

  1. Используйте следующий код для преобразования Bitmap в BitmapImage.

    using (MemoryStream memory = new MemoryStream())
    {
        NwImg.Save(memory, ImageFormat.Jpeg);
        memory.Position = 0;
        Nwbi = new BitmapImage();
        Nwbi.BeginInit();
        Nwbi.StreamSource = memory;
        Nwbi.CacheOption = BitmapCacheOption.OnLoad;
        Nwbi.EndInit();
    }
    
  2. Внутри вашего класса Pic замените эти строки

    //Save to current picture
    Bitmap NewImage = new Bitmap(BottomImage.Width, BottomImage.Height, canvas);
    return NewImage;
    

    к этому

    return BottomImage;
    

    поскольку перегрузка используемого вами класса Bitmap не создает новое растровое изображение на основе объекта Graphics, а только его разрешение (это приводит к пустому изображению). Итак, поскольку вы рисуете на растровое изображение BottomImage, вам просто нужно вернуть это изображение.

введите здесь описание изображения

person David -    schedule 18.07.2013
comment
СПАСИБО БОЛЬШОЕ ДАВИД!!!!! ОНО РАБОТАЕТ!!!!! Мне нужно будет больше узнать об изображениях, я действительно не знаю, читая библиотеки, что это то, что делает графика. Спасибо еще раз. - person chris; 18.07.2013

Переменная «память» не может быть нулевой в строке, где вы прокомментировали «поток памяти показывает нуль», когда эта строка выполняется, потому что она определенно назначена в блоке «использование» на 4 строки выше нее. Я предполагаю, что вы слишком рано поставили точку останова отладчика в методе. Попробуйте поставить точку останова на строку, где вы назначаете Nwbi.CacheOption, и посмотрите, скажет ли отладчик то, что вы ожидали.

person Matthew Schaad    schedule 18.07.2013
comment
Это нулевое значение. Сначала я запустил его без перерывов и заметил, что изображение не обновлялось, затем я просматривал код в обратном направлении и запускал его несколько раз, и в этот момент я теряю изображение, Nwbi показывает ноль вне использования - person chris; 18.07.2013