Setting image in the view after downloading from web with JSON.Net - c#

Let's say I have 3 image views in my xaml . I am downloading images from a server & now I want to set those images in my image views . How can I do that ? Please Help !
My Code :
void webClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
//parse data
var container = DeserializeFromJson<DataJsonAttributeContainer>(e.Result);
//load into list
for (int i = 0; i < container.MyBookList.Count; i++)
{
newData[i] = new data();
newData[i].id = container.MyBookList[i].ID;
newData[i].title = container.MyBookList[i].TITLE;
newData[i].type = container.MyBookList[i].TYPE;
newData[i].price = container.MyBookList[i].PRICE;
newData[i].downloadLink = container.MyBookList[i].DOWNLOADLINK;
string file_name = newData[i].downloadLink.ToString();
string image_uri = "http://www.banglanews24.com/images/imgAll/" + file_name;
WebClient wc = new WebClient();
wc.OpenReadCompleted += new OpenReadCompletedEventHandler(wc_OpenReadCompleted);
wc.OpenReadAsync(new Uri(image_uri), wc);
}
void wc_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
if (e.Error == null && !e.Cancelled)
{
try
{ //I can set just one image here....what should I do ?
BitmapImage image = new BitmapImage();
image.SetSource(e.Result);
image1.Source = image;
}
catch (Exception ex)
{
//Exception handle appropriately for your app
}
}
else
{
//Either cancelled or error handle appropriately for your app
}
}

This should do it:
void webClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
//parse data
var container = DeserializeFromJson<DataJsonAttributeContainer>(e.Result);
//load into list
for (int i = 0; i < container.MyBookList.Count; i++)
{
newData[i] = new data();
newData[i].id = container.MyBookList[i].ID;
newData[i].title = container.MyBookList[i].TITLE;
newData[i].type = container.MyBookList[i].TYPE;
newData[i].price = container.MyBookList[i].PRICE;
newData[i].downloadLink = container.MyBookList[i].DOWNLOADLINK;
string file_name = newData[i].downloadLink.ToString();
string image_uri = "http://www.banglanews24.com/images/imgAll/" + file_name;
Uri uri = new Uri(image_uri, UriKind.Relative);
ImageSource imgSource = new BitmapImage(uri);
if (i==0) image1.source = imgSource;
else if (i==1) image2.source = imgSource;
else if (i==2) image3.source = imgSource;
etc
}
You will find that your images will automatically be downloaded when you give it a Image URI.

Related

Image.Source = new BitmapImage(); doesn't work in UWP

I have a problem while reading a file in C#. Here's the code:
protected override void OnNavigatedTo(NavigationEventArgs EvArgs)
{
base.OnNavigatedTo(EvArgs);
var Args = EvArgs.Parameter as Windows.ApplicationModel.Activation.IActivatedEventArgs;
var FArgs = Args as Windows.ApplicationModel.Activation.FileActivatedEventArgs;
if (Args != null)
{
if (Args.Kind == Windows.ApplicationModel.Activation.ActivationKind.File)
{
var IMG = new Image();
IMG.Loaded += IMG_Loaded;
string FP = FArgs.Files[0].Path;
Uri = FP;
IMG.Source = new BitmapImage(new Uri(FP, UriKind.RelativeOrAbsolute));
FV.Items.Add(IMG);
PathBlock.Text = FArgs.Files[0].Name + " - Image Viewer";
void IMG_Loaded(object sender, RoutedEventArgs e)
{
IMG.Source = new BitmapImage(new Uri(Uri));
}
}
}
if (Args == null)
{
PathBlock.Text = "Image Viewer";
}
}
The problem is at this part:
IMG.Source = new BitmapImage(new Uri(FP, UriKind.RelativeOrAbsolute));
The image won't load, even after trying a resource that the app CAN access in its own files:
IMG.Source = new BitmapImage(new Uri("ms-appx:///09.png, UriKind.RelativeOrAbsolute));
It still won't work.
This only works with this code:
var FOP = new Windows.Storage.Pickers.FileOpenPicker();
StorageFile F = await FOP.PickSingleFileAsync();
IRandomAccessStream FS = await F.OpenAsync(FileAccessMode.Read);
var BI = new BitmapImage();
var IMG = new Image();
await BI.SetSourceAsync(FS);
IMG.Source = BI;
Sadly, I can't use a file stream OR a file picker in the first code example, so I can't make it work as I did here.
Image.Source = new BitmapImage(); doesn't work in UWP
The problem is file Path property does not use to set image source directly in UWP platform.
Derive from your code, it looks you open the image file with current app, if you can get the IStorageItem from FArgs.Files list, you could also convert it as StorageFile, and then pass the opened file stream to BitmapImage.
For more detail steps please refer to the following code.
protected async override void OnNavigatedTo(NavigationEventArgs EvArgs)
{
base.OnNavigatedTo(EvArgs);
var Args = EvArgs.Parameter as Windows.ApplicationModel.Activation.IActivatedEventArgs;
var FArgs = Args as Windows.ApplicationModel.Activation.FileActivatedEventArgs;
if (Args != null)
{
if (Args.Kind == Windows.ApplicationModel.Activation.ActivationKind.File)
{
var IMG = new Image();
string FP = FArgs.Files[0].Path;
var Uri = FP;
StorageFile imageFile = FArgs.Files[0] as StorageFile;
using (var stream = await imageFile.OpenReadAsync())
{
var bitmp = new BitmapImage();
bitmp.SetSource(stream);
IMG.Loaded += (s, e) => { IMG.Source = bitmp; };
}
RootLayout.Children.Add(IMG);
}
}
if (Args == null)
{
}
}

image doesn't change - WPF

I'm trying to change an image on runtime but it's not working.
I have a user control that when you click on imagebtn it's opening a new window with a list of images.
the next step is to take the image selected from the list, close the new window, and put the image on the imagebtn.
the user control still opens in the background.
this is my code.
NewWindow:
private string myData;
public ImagesWindow()
{
InitializeComponent();
InitialImageList();
}
private async void InitialImageList()
{
//add try catch
string get = await HttpRequests.GetRequest(URLImages);
allJsonCategory = JsonConvert.DeserializeObject<List<ImageArray>>(get);
Console.WriteLine(get);
ImageBoxList.ItemsSource = images;
foreach (var item in allJsonCategory)
{
images.Add(item);
}
}
private void ImageBoxList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
selectedImage = (ImageArray)ImageBoxList.SelectedItem;
myData = selectedImage.full_path;
Console.WriteLine("you clicked on: " + selectedImage.name);
ProductsCategory pro = new ProductsCategory();
pro.imagePath = myData;
this.Close();
}
my usercontrol(in mainWindow):
public void setImage(string imagePath)
{
if (!imageURL.Equals(""))
{
Image imageBtn = new Image();
var imgUrl = new Uri(imagePath);
var imageData = new WebClient().DownloadData(imgUrl);
// or you can download it Async won't block your UI
// var imageData = await new WebClient().DownloadDataTaskAsync(imgUrl);
var bitmapImage = new BitmapImage { CacheOption = BitmapCacheOption.OnLoad };
bitmapImage.BeginInit();
bitmapImage.StreamSource = new MemoryStream(imageData);
bitmapImage.EndInit();
imageBtn.Source = bitmapImage;
//this.imageBtn.InvalidateVisual();
}
}
XAML of the image:
where is my mistake?
thank you all :)

WinForms DataGridView does not respond while listing images

I have an application that allows the users to upload the selected images to the DataGridView and perform operations on their. However, when multiple images are selected, the Form freezes until the image information is uploaded to the DataGridView. I have tried BackgroundWorker for this, but it didn't work either. My codes look like this:
private void button1_Click(object sender, EventArgs e)
{
var file = new OpenFileDialog
{
Filter = #"TIFF |*.tiff| TIF|*.tif",
FilterIndex = 1,
Title = #"Select TIFF file(s)...",
Multiselect = true
};
if (file.ShowDialog() == DialogResult.OK)
{
Listing(file.FileNames);
}
}
private void Listing(string[] files)
{
foreach (var file in files)
{
var pic_name = Path.GetFileName(file);
if (file != null)
{
// Image from file
var img = Image.FromFile(file);
// Get sizes of TIFF image
var pic_sizes = img.Width + " x " + img.Height;
// Get size of TIFF image
var pic_size = new FileInfo(file).Length;
//Create the new row first and get the index of the new row
var rowIndex = dataGridView1.Rows.Add();
//Obtain a reference to the newly created DataGridViewRow
var row = dataGridView1.Rows[rowIndex];
//Now this won't fail since the row and columns exist
row.Cells["name"].Value = pic_name;
row.Cells["sizes"].Value = pic_sizes + " pixels";
row.Cells["size"].Value = pic_size + " bytes";
}
}
}
How can I solve this problem?
EDIT: After Alex's comment, I tried like this:
private void button1_Click(object sender, EventArgs e)
{
var file = new OpenFileDialog
{
Filter = #"TIFF |*.tiff| TIF|*.tif",
FilterIndex = 1,
Title = #"Select TIFF file(s)...",
Multiselect = true
};
if (file.ShowDialog() == DialogResult.OK)
{
_ = Test(file.FileNames);
}
}
private async Task Test(string[] s)
{
await Task.Run(() => Listing(s));
}
private void Listing(string[] files)
{
BeginInvoke((MethodInvoker) delegate
{
foreach (var file in files)
{
var pic_name = Path.GetFileName(file);
if (file != null)
{
// Image from file
var img = Image.FromFile(file);
// Get sizes of TIFF image
var pic_sizes = img.Width + " x " + img.Height;
// Get size of TIFF image
var pic_size = new FileInfo(file).Length;
//Create the new row first and get the index of the new row
var rowIndex = dataGridView1.Rows.Add();
//Obtain a reference to the newly created DataGridViewRow
var row = dataGridView1.Rows[rowIndex];
//Now this won't fail since the row and columns exist
row.Cells["name"].Value = pic_name;
row.Cells["sizes"].Value = pic_sizes + " pixels";
row.Cells["size"].Value = pic_size + " bytes";
}
}
});
}
But unfortunately the result is same.
I think the whole problem is in collecting image datas. Because a ready list will not take longer to load if it will not need extra processing. For this reason, I prepared a scenario like below.
private readonly BindingList<Tiff> _tiffs = new BindingList<Tiff>();
private void button1_Click(object sender, EventArgs e)
{
Listing();
}
private void Listing()
{
foreach (var f in _tiffs)
{
if (f != null)
{
var rowIndex = dataGridView1.Rows.Add();
//Obtain a reference to the newly created DataGridViewRow
var row = dataGridView1.Rows[rowIndex];
//Now this won't fail since the row and columns exist
row.Cells["ColName"].Value = f.ColName;
row.Cells["ColSizes"].Value = f.ColSizes + " pixels";
row.Cells["ColSize"].Value = f.ColSize + " bytes";
}
}
}
public static List<string> Files(string dir, string ext = "*.tiff")
{
var DirInfo = new DirectoryInfo(dir);
return DirInfo.EnumerateFiles(ext, SearchOption.TopDirectoryOnly).Select(x => x.FullName).ToList();
}
public void SetSource()
{
// Source folder of images...
var files = Files(#"___SOURCE_DIR___");
var total = files.Count;
var i = 1;
foreach (var file in files)
{
var pic_name = Path.GetFileName(file);
var img = Image.FromFile(file);
// Get sizes of TIFF image
var pic_sizes = img.Width + " x " + img.Height;
// Get size of TIFF image
var pic_size = new FileInfo(file).Length.ToString();
_tiffs.Add(new Tiff(pic_name, pic_sizes, pic_size));
BeginInvoke((MethodInvoker)delegate
{
label1.Text = $#"{i} of {total} is added to the BindingList.";
});
i++;
}
}
private void button2_Click(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
SetSource();
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
// Set something if you want.
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// Set something if you want.
}
public class Tiff
{
public Tiff(string name, string sizes, string size)
{
ColName = name;
ColSizes = sizes;
ColSize = size;
}
public string ColName { get; set; }
public string ColSizes { get; set; }
public string ColSize { get; set; }
}
And here is the result:

unable to display captured image in windows phone listview

I am trying to display the captured image in windows phone listview in order to upload using background agent. But when the cameracapturedtask is completing, the app is deactivating in app.xaml.cs. This same functionality is working fine when I upload image from Gallery. I have included my code below. Please help if there is any solution.
private void Camera_Click(object sender, RoutedEventArgs e)
{
cmb.Dismiss();
CameraCaptureTask cameraCapture = new CameraCaptureTask();
cameraCapture.Completed += new EventHandler<PhotoResult>(cameraCaptureTask_Completed);
cameraCapture.Show();
}
private void cameraCaptureTask_Completed(object sender, PhotoResult e)
{
if (e.TaskResult == TaskResult.OK)
{
string filename = e.OriginalFileName;
var listSplit = filename.Split('\\');
int i = listSplit.Length;
string name = listSplit[i - 1];
PhotoResult photoResult = e;
j = 1;
//sendImgRequest(name, e);
BitmapImage bmp = new BitmapImage();
bmp.SetSource(e.ChosenPhoto);
arrfilename.Add(filename);
//arrimg.Add(bmp);
arrstream.Add(e.ChosenPhoto);
arrtext.Add("Photo");
using (var isostore = IsolatedStorageFile.GetUserStoreForApplication())
{
var wb = new WriteableBitmap(bmp);
using (var isoFileStream = isostore.CreateFile(name))
wb.SaveJpeg(isoFileStream, wb.PixelWidth, wb.PixelHeight, 0, 100);
}
newimgdata.Add(new imgdata { image = bmp, text = "Photo", filename = name });
lstbox.ItemsSource = newimgdata;
}
}

How to load image from isolated storage for secondary tile

I am attempting to populate a secondary tile background with an image saved from the PhotoChooserTask, but for some reason I cannot accomplish this. I have referenced a lot of sites but I have not found the proper implementation. All I do is call PhotoChooserTask, and then on the completed event I save the resulting image to isolated storage to be loaded later. This has worked with a HubTile in my application, but for some reason I cannot append the image to a secondary tile. So far what I have is as follows:
MainPage.xaml.cs
string imageFolder = #"\Shared\ShellContent";
string shareJPEG = "shareImage.jpg";
public MainPage()
{
InitializeComponent();
photoChooserTask = new PhotoChooserTask();
photoChooserTask.Completed += new EventHandler<PhotoResult>(photoChooserTask_Completed);
}
public void changePictureMenuItem_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
try
{
photoChooserTask.Show();
}
catch (System.InvalidOperationException)
{
MessageBox.Show("An error occurred");
}
}
void photoChooserTask_Completed(object sender, PhotoResult e)
{
if (e.TaskResult == TaskResult.OK)
{
//persist the data in isolated storage
using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
if(!myIsolatedStorage.DirectoryExists(imageFolder))
{
myIsolatedStorage.CreateDirectory(imageFolder);
}
if (myIsolatedStorage.FileExists(shareJPEG))
{
myIsolatedStorage.DeleteFile(shareJPEG);
}
string filePath = System.IO.Path.Combine(imageFolder, shareJPEG);
IsolatedStorageFileStream fileStream = myIsolatedStorage.CreateFile(filePath);
BitmapImage bitmap = new BitmapImage();
bitmap.SetSource(e.ChosenPhoto);
WriteableBitmap wb = new WriteableBitmap(bitmap);
// Encode WriteableBitmap object to a JPEG stream.
Extensions.SaveJpeg(wb, fileStream, 173, 173, 0, 100);
fileStream.Close();
}
}
}
private void CreateLiveTile(TileItem item)
{
//IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication();
var title = item.Title.ToString();
string tileParameter = "Param=" + item.Title.ToString();
ShellTile Tile = CheckIfTileExist(tileParameter); // Check if Tile's title has been used
if (Tile == null)
{
//this is not working?
background = new Uri(#"isostore:/Shared/ShellContent/shareJPEG.png", UriKind.Absolute);
//background = new Uri("isostore:/Shared/ShellContent/shareJPEG.png", UriKind.Absolute);
try
{
var LiveTile = new StandardTileData
{
Title = item.TileName,
BackgroundImage = background, //not working
BackTitle = item.TileName,
BackBackgroundImage = new Uri("/background.png", UriKind.Relative),
BackContent = item.Message,
};
ShellTile.Create(new Uri("/MainPage.xaml?" + tileParameter, UriKind.Relative), LiveTile);
}
}
Ultimately, the secondary tile is created but there is no image for the BackgroundImage. How would I properly call the isolated strorage path to set the BackgroundImage of the secondary tile accordingly? Or is there something else I should be doing or change?
MainPage.xaml.cs
string imageFolder = #"\Shared\ShellContent";
string shareJPEG = "shareImage.jpg";
...
private void CreateLiveTile(TileItem item)
{
var title = item.Title.ToString();
string tileParameter = "Param=" + item.Title.ToString();
ShellTile Tile = CheckIfTileExist(tileParameter); // Check if Tile's title has been used
if (Tile == null)
{
string filePath = System.IO.Path.Combine(imageFolder, shareJPEG);
background = new Uri(#"isostore" + filePath, UriKind.Absolute); //this worked
...
}
}
Are you sure the image is saved successfully and exists? You save it as jpeg but you reference a png file. Try #"\Shared\ShellContent\shareJPEG.png"
first you should put your image at "\Shared\ShellContent" location. you can use .png or .jpg file
string imageFolder = #"\Shared\ShellContent";
string shareJPEG = "shareImage.jpg";
...
private void CreateLiveTile(TileItem item)
{
var title = item.Title.ToString();
string tileParameter = "Param=" + item.Title.ToString();
ShellTile Tile = CheckIfTileExist(tileParameter);
if (Tile == null)
{
string filePath = System.IO.Path.Combine(imageFolder, shareJPEG);
using (var iso = IsolatedStorageFile.GetUserStoreForApplication())
{
if (iso.FileExists(filePath)) // check file exist or not
background = new Uri(#"isostore:" + filePath, UriKind.Absolute);
}
...
}
}

Categories