WriteableBitmap не делает недействительными и отображает в Windows Phone, но работает в silverlight5? - PullRequest
2 голосов
/ 15 февраля 2012

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

(Imageproperty as WriteableBitmap) .Invalidate ();

<Image Source="{Binding Imageproperty}"/> (this is working in silverlight not in WP(7.1))

Ответы [ 3 ]

1 голос
/ 05 марта 2012

У меня была похожая проблема при попытке перенести часть кода FaceLight с Silverlight на Windows Phone.Самый простой способ обойти это - вручную установить значение альфа 255 / непрозрачный.Например, если у вас есть ваш WriteableBitmap, который вы хотите отобразить, result :

        //convert to byte array
        int stride = result.PixelWidth * 4; //brga32 is 32            
        int bytes = Math.Abs(stride) * result.PixelHeight;
        byte[] data = result.ToByteArray();

        int dataIndex = 0;
        int nOffset = stride - result.PixelWidth * 4;
        for (int y = 0; y < result.PixelHeight; ++y)
        {
            for (int x = 0; x < result.PixelWidth; ++x)
            {
                data[dataIndex + 3] = 0xFF;   //set alpha to 255
                dataIndex += 4;               //skip to next pixel
            }
            dataIndex += nOffset;
        }

        WriteableBitmap finalImg = new WriteableBitmap(input.PixelWidth, input.PixelHeight);            
        return finalImg.FromByteArray(data);

Отображение результата этого метода (вызов finalImg.FromByteArray (data)) должен правильно отображаться нателефон.

Альтернативой этому методу, описанному выше, является также запись WriteableBitmap в .jpeg, а затем отображение .jpeg вместо этого - мне это тоже показалось, но я не слишком тщательно исследовал это.

0 голосов
/ 10 мая 2015

Я знаю, что это старый пост, но сегодня я столкнулся с той же проблемой на Windows Phone 8.1 Silverlight, и я нашел хорошее решение, поэтому я решил оставить его для людей с подобной проблемой.Он был опубликован Чарльзом Петцольдом на MSDN как Видеопотоки на Windows Phone 7 (это показано на примере класса VideoSink, но не должно быть проблемой воспроизвести его в другом случае).Он создал простой класс, производный от VideoSink:

SimpleVideoSink C # code:

public class SimpleVideoSink : VideoSink
{
  VideoFormat videoFormat;
  WriteableBitmap writeableBitmap;
  Action<WriteableBitmap> action;
  public SimpleVideoSink(Action<WriteableBitmap> action)
  {
    this.action = action;
  }
  protected override void OnCaptureStarted() { }
  protected override void OnCaptureStopped() { }
  protected override void OnFormatChange(VideoFormat videoFormat)
  {
    this.videoFormat = videoFormat;
    System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() =>
    {
      writeableBitmap = new WriteableBitmap(videoFormat.PixelWidth,
        videoFormat.PixelHeight);
      action(writeableBitmap);
    });
  }
  protected override void OnSample(long sampleTimeInHundredNanoseconds,
    long frameDurationInHundredNanoseconds, byte[] sampleData)
  {
    if (writeableBitmap == null)
      return;
    int baseIndex = 0;
    for (int row = 0; row < writeableBitmap.PixelHeight; row++)
    {
      for (int col = 0; col < writeableBitmap.PixelWidth; col++)
      {
        int pixel = 0;
        if (videoFormat.PixelFormat == PixelFormatType.Format8bppGrayscale)
        {
          byte grayShade = sampleData[baseIndex + col];
          pixel = (int)grayShade | (grayShade << 8) |
            (grayShade << 16) | (0xFF << 24);
        }
        else
        {
          int index = baseIndex + 4 * col;
          pixel = (int)sampleData[index + 0] | (sampleData[index + 1] << 8) |
            (sampleData[index + 2] << 16) | (sampleData[index + 3] << 24);
        }
        writeableBitmap.Pixels[row * writeableBitmap.PixelWidth + col] = pixel;
      }
      baseIndex += videoFormat.Stride;
    }
    writeableBitmap.Dispatcher.BeginInvoke(() =>
      {
        writeableBitmap.Invalidate();
      });
  }
}

Однако этот код нуждается в некоторой модификации - VideoSink.CaptureSource должен быть предоставлен с CaptureSource(Я только что передал его в конструктор):

public SimpleVideoSink(CaptureSource captureSource, Action<WriteableBitmap> action)
{
    base.CaptureSource = captureSource;
    this.action = action;
}

Когда мы инициализируем класс SimpleVideoSink в ViewModel, мы должны предоставить ему параметр Action.В моем случае было достаточно предоставить ViewModel инициализированное поле writeableBitmap:

ViewModel C # code:

private WriteableBitmap videoWriteableBitmap;

public WriteableBitmap VideoWriteableBitmap
{
    get
    {
        return videoWriteableBitmap;
    }
    set
    {
        videoWriteableBitmap = value;
        RaisePropertyChanged("VideoWriteableBitmap");
    }
}

private void OnWriteableBitmapChange(WriteableBitmap writeableBitmap)
{
    VideoWriteableBitmap = writeableBitmap;
}

//this part goes to constructor/method
SimpleVideoSink videoFrameHandler = new SimpleVideoSink(captureSource, OnWriteableBitmapChange);

Тогда все, что нам нужно сделать, это привязать его к View:

Просмотр кода XAML:

<Image Source="{Binding VideoWriteableBitmap}" />

В этом примере Image источник обновляется при каждом вызове метода OnSample и отправляется в основной поток через WriteableBitmap.Dispatcher.

Это решение генерирует правильное изображение без пустого пикселя (альфа-канал также заполнен), а метод Invalidate() работает как следует.

0 голосов
/ 15 февраля 2012

Если у writeablebitmap есть установленные или измененные пиксельные данные после установления привязки, вам нужно вызвать Invalidate , чтобы вызвать обновление экрана.

Это относится и к Silverlight, и к Phone, но у вас может быть условие гонки, которое работает по-разному на обеих платформах.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...