From cfe7498c60ddc320a76106981a3dd67baa1ffe3c Mon Sep 17 00:00:00 2001 From: Andy Himberger Date: Fri, 28 Jun 2019 13:18:27 -0700 Subject: [PATCH 1/2] add basic base64 image support --- vnext/ReactUWP/Views/Image/ReactImage.cpp | 35 ++++++++++++++++++++++- vnext/ReactUWP/Views/Image/ReactImage.h | 1 + vnext/Universal.SampleApp/index.uwp.js | 9 ++++++ 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/vnext/ReactUWP/Views/Image/ReactImage.cpp b/vnext/ReactUWP/Views/Image/ReactImage.cpp index f52e90b810c..981e5e1177e 100644 --- a/vnext/ReactUWP/Views/Image/ReactImage.cpp +++ b/vnext/ReactUWP/Views/Image/ReactImage.cpp @@ -6,6 +6,7 @@ #include "ReactImage.h" #include +#include #include "unicode.h" @@ -75,6 +76,7 @@ namespace react { winrt::Uri uri{ facebook::utf8ToUtf16(uriString) }; winrt::hstring scheme{ uri.SchemeName() }; bool needsDownload = (scheme == L"http") || (scheme == L"https"); + bool inlineData = scheme == L"data"; try { @@ -90,10 +92,14 @@ namespace react { m_onLoadEndEvent(*this, false); } } + else if (inlineData) + { + memoryStream = co_await GetImageInlineDataAsync(source); + } if (!needsDownload || memoryStream) { - auto surface = needsDownload ? + auto surface = needsDownload || inlineData ? winrt::LoadedImageSurface::StartLoadFromStream(memoryStream) : winrt::LoadedImageSurface::StartLoadFromUri(uri); @@ -166,5 +172,32 @@ namespace react { return nullptr; } + + winrt::IAsyncOperation GetImageInlineDataAsync(ImageSource source) + { + size_t start = source.uri.find(','); + if (start == std::string::npos || start + 1 > source.uri.length()) + return nullptr; + + try + { + co_await winrt::resume_background(); + + std::string_view base64String(source.uri.c_str() + start + 1, source.uri.length() - start - 1); + auto buffer = winrt::Windows::Security::Cryptography::CryptographicBuffer::DecodeFromBase64String(facebook::react::unicode::utf8ToUtf16(base64String)); + + winrt::InMemoryRandomAccessStream memoryStream; + co_await memoryStream.WriteAsync(buffer); + memoryStream.Seek(0); + + return memoryStream; + } + catch (winrt::hresult_error const&) + { + // Base64 decode failed + } + + return nullptr; + } } } // namespace react::uwp diff --git a/vnext/ReactUWP/Views/Image/ReactImage.h b/vnext/ReactUWP/Views/Image/ReactImage.h index 61213da6782..e1711ee251e 100644 --- a/vnext/ReactUWP/Views/Image/ReactImage.h +++ b/vnext/ReactUWP/Views/Image/ReactImage.h @@ -62,5 +62,6 @@ namespace react { // Helper functions winrt::Windows::Foundation::IAsyncOperation GetImageStreamAsync(ImageSource source); + winrt::Windows::Foundation::IAsyncOperation GetImageInlineDataAsync(ImageSource source); } } // namespace react::uwp diff --git a/vnext/Universal.SampleApp/index.uwp.js b/vnext/Universal.SampleApp/index.uwp.js index 9676460384a..04596d9bcd9 100644 --- a/vnext/Universal.SampleApp/index.uwp.js +++ b/vnext/Universal.SampleApp/index.uwp.js @@ -262,6 +262,15 @@ export default class Bootstrap extends Component { onError={() => { console.log('image onError!'); }} /> + + + this.setState({ checkBoxIsOn: value })} From 3b7a107b587c33e00d46d20af0c03474e28d08e1 Mon Sep 17 00:00:00 2001 From: Marlene Cota Date: Fri, 28 Jun 2019 22:51:18 -0700 Subject: [PATCH 2/2] Fire onError event if GetImageInlineDataAsync fails --- vnext/ReactUWP/Views/Image/ReactImage.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/vnext/ReactUWP/Views/Image/ReactImage.cpp b/vnext/ReactUWP/Views/Image/ReactImage.cpp index 981e5e1177e..9555c4c78bb 100644 --- a/vnext/ReactUWP/Views/Image/ReactImage.cpp +++ b/vnext/ReactUWP/Views/Image/ReactImage.cpp @@ -86,17 +86,17 @@ namespace react { if (needsDownload) { memoryStream = co_await GetImageStreamAsync(source); - - if (!memoryStream) - { - m_onLoadEndEvent(*this, false); - } } else if (inlineData) { memoryStream = co_await GetImageInlineDataAsync(source); } + if ((needsDownload || inlineData) && !memoryStream) + { + m_onLoadEndEvent(*this, false); + } + if (!needsDownload || memoryStream) { auto surface = needsDownload || inlineData ?