7

Tôi đang cố gắng hiển thị tệp ảnh GIF được lưu trữ trong Windows Phone 8.1 (RT) thư mục cục bộ của ứng dụng. Cho đến bây giờ, tôi đã thử một số cách tiếp cận:Cách hiển thị GIF động trong ứng dụng Windows Phone 8.1 (RT)?

  1. Tải GIF trong điều khiển WebView. Đây không phải là giải pháp vì tôi muốn hiển thị hình ảnh trong điều khiển FlipView (tôi không thể lật sang hình ảnh khác). Ngoài ra, nó là khá chậm.
  2. Lấy khung hình GIF bằng cách sử dụng lớp BitmapDecoder và tạo ảnh động bằng cách sử dụng bảng phân cảnh.

    Mã này là như sau:

using (var stream = await storageFile.OpenReadAsync()) 
    { 
     //I don't specify the type since I would like to load other type of images also 
     //It doesn't make any difference if I would use "BitmapDecoder.GifDecoderId" 

     var decoder = await BitmapDecoder.CreateAsync(stream); 
     uint frameCount = decoder.FrameCount; 

     for (uint frameIndex = 0; frameIndex < frameCount; frameIndex++) 
     { 
      var frame = await decoder.GetFrameAsync(frameIndex); 
      var writableBitmap = new WriteableBitmap((int)decoder.OrientedPixelWidth, 
                (int)decoder.OrientedPixelHeight); 

      var pixelDataProvider = await frame.GetPixelDataAsync 
       (BitmapPixelFormat.Bgra8, 
       decoder.BitmapAlphaMode, new BitmapTransform(), 
       ExifOrientationMode.IgnoreExifOrientation, 
       ColorManagementMode.DoNotColorManage); 

      var pixelData = pixelDataProvider.DetachPixelData(); 
      using (var pixelStream = writableBitmap.PixelBuffer.AsStream()) 
      { 
       pixelStream.Write(pixelData, 0, pixelData.Length); 
      } 

      _bitmapFrames.Add(writableBitmap); 
     } 
    } 

Vấn đề là rằng khung tôi nhận được từ các hình ảnh GIF được sai lầm

like this one

Tôi có làm điều gì sai trong cách tiếp cận này? Tôi nên sửa đổi điều gì để có được kết quả tốt?

Tôi không muốn sử dụng SharpDX vì nó có vẻ rất phức tạp và tôi là người mới bắt đầu.

ImageTools chỉ có sẵn cho Silverlight

+0

Mọi người vẫn sử dụng hoạt ảnh .gif những ngày này? Tôi ghét thậm chí phải đề xuất giữ nó, nhưng bạn chỉ có thể làm '' - Mặc dù tôi đoán nếu bạn sẽ giữ nó, hãy cho tôi biết và tôi sẽ đặt nó như trả lời để tôi có thể ghi lại một số điểm dễ dàng. :) –

+1

Tôi đã thử thêm MediaElement vào trang và đặt tệp gif làm nguồn của nó. Sau khi tôi đã đặt 'AreTransportControlsEnabled' thành true, tôi có thể thấy lỗi nói 'Loại video không được hỗ trợ hoặc đường dẫn tệp không hợp lệ'. Ngoài ra, đường dẫn đến tệp GIF đã được đặt chính xác. – rhcpfan

+0

Có thể đã thề tôi đã sử dụng nó trước đây, có lẽ không phải là WP mặc dù? Tôi sẽ tinker với nó sau này nếu tôi có thời gian. Xin lỗi vì điều đó. –

Trả lời

6

tôi đã thực hiện một rất cơ bản GifImage điều khiển mà bạn có thể bắt đầu từ đâu. Đây là một điểm khởi đầu, bạn sẽ phải cải thiện nó để làm cho nó dễ sử dụng hơn như một điều khiển tái sử dụng. Kiểm tra xem nó ra here.

GifImage windows phone screenshot


EDIT

Bạn có bất cứ ý tưởng làm thế nào để cải thiện tốc độ tải (song song, vv)?

Tôi giả sử bạn đang đề cập đến quá trình chuẩn bị khung. Từ những gì tôi đã thử nghiệm, nó có vẻ tải ngay lập tức anyway, do đó, không nên có một nhu cầu cải tiến hiệu suất quyết liệt. Tuy nhiên, nếu có lẽ phim hoạt hình có hàng trăm khung hình, thì đó có thể là một nút cổ chai có thể? Cần thực hiện nhiều thử nghiệm hơn để đánh giá xem có cần tối ưu hóa hay không.

Tôi cũng không nghĩ rằng nó có thể được song song một cách dễ dàng vì mỗi khung hình cần được hiển thị theo thứ tự từ khung trước đó. Đề xuất duy nhất của tôi là chạy mã tải trên chuỗi nền để chuỗi giao diện người dùng không chặn hình ảnh lớn.

Nếu tôi có điều khiển này dưới dạng FlipViewItem, làm cách nào tôi có thể giải phóng bộ nhớ sau khi mục bị lật?

Tôi không chắc chắn hay không, bạn đang sử dụng MVVM hay không, nhưng dù sao, đây là một số gợi ý:

  • Đặt Source của GifImage null nếu nó không hiện hữu (kiểm tra SelectedIndex của chế độ xem lật). Lưu ý rằng hiện tại mã trong repo của tôi không xử lý cài đặt Source thành vô giá trị. Như tôi đã nói trước đây, nó cần rất nhiều cải tiến. Bạn sẽ phải đảm bảo rằng điều khiển không giữ bất kỳ tham chiếu nào đến các khung để bộ thu gom rác có thể giải phóng chúng khỏi bộ nhớ (nghĩa là, gọi animation.KeyFrames.Clear() để xóa tất cả các tham chiếu đến các khung).
  • Sử dụng VirtualizingStackPanel bên trong chế độ xem lật. Điều này sẽ đảm bảo rằng chỉ các mục xem trước đó, hiện tại và tiếp theo được tạo trong bộ nhớ. Bạn đặt nó như sau:
<FlipView> 
    <FlipView.ItemsPanel> 
     <ItemsPanelTemplate> 
      <VirtualizingStackPanel Orientation="Horizontal" /> 
     </ItemsPanelTemplate> 
    </FlipView.ItemsPanel> 
</FlipView> 
+0

Cảm ơn bạn đã giải pháp! Tôi đã thực hiện chỉ thử nghiệm nhỏ, nhưng nó hoạt động tốt. Bạn có biết cách cải thiện tốc độ tải (song song, v.v.) không? Ngoài ra, nếu tôi có điều khiển này dưới dạng FlipViewItem, làm thế nào tôi có thể giải phóng bộ nhớ sau khi mục bị lật? Cảm ơn bạn lần nữa! – rhcpfan

2

Tôi cũng gặp vấn đề tương tự. Tôi đã cố gắng để hiển thị một GIF động được tải từ một nguồn bên ngoài bên trong một ứng dụng ScrollViewer cho Windows Phone 8.1. Kể từ khi kiểm soát web mất hơn các sự kiện di chuyển đã không làm việc.

Tôi đã sử dụng mẹo này: Tôi đã đặt điều khiển web bên trong lưới và đặt một lưới khác trên webcontrol. Lưới trên điều khiển web được đặt thành kích thước chính xác và tôi đặt nền thành trong suốt. Bằng cách này lưới nhận được các sự kiện và di chuyển hoạt động trở lại.

<ScrollViewer Visibility="Visible" HorizontalAlignment="Left" VerticalAlignment="Top" Width="380"> 
    <Grid> 
     <StackPanel> 

      <!-- 
      Some items ... 
      --> 

      <Grid > 
       <WebView x:Name="animationWebView" HorizontalAlignment="Left" Height="315" Width="390" Visibility="Visible" /> 
       <Grid Width="390" Height="315" Background="Transparent" /> 
      </Grid> 

      <!-- 
      Some other items ... 
      --> 
     </StackPanel> 
    </Grid> 
</ScrollViewer> 
Các vấn đề liên quan