I've created a method that reads .jpg files and displays them on my screen without extracting.
The var looks like this
var imageName = content.contentid + ".jpg";
content.contentid is too id number of the number + .jpg
But now I want that if there is, for example, a png or jfif file in the zip that it also just shows it.
How do I handle this in this method?
This is my code so far
private void getImage()
{
try
{
var folderName = "protocol-" + _protocol.id + "-" + _protocol.versionnr + ".zip";
var extractPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
var zipPath = $"{extractPath}" + "/" + $"{folderName}";
var currentIndex = getCurrentIndex();
var content = _protocol.contents[currentIndex];
List<string> allowedExtensions = new List<string>() { "jpg", "png", "jfif" };
using (var archive = ZipFile.OpenRead(zipPath))
{
foreach (var pictureEntry in archive.Entries)
if (Path.GetFileNameWithoutExtension(pictureEntry.Name).Equals(content.contentid) && allowedExtensions.Contains(Path.GetExtension(pictureEntry.Name)))
{
byte[] buffer;
var length = pictureEntry.Length;
buffer = new byte[length];
pictureEntry.Open().Read(buffer, 0, (int)length);
myImage.Source = ImageSource.FromStream(() => new MemoryStream(buffer));
}
}
}
catch (Exception)
{
}
}
Well you can try this approach:
First define a List of extensions that you want to check against:
List<string> allowedExtensions = new List<string>() {"jpg", "png", "jfif" };
then change your if (pictureEntry.Name == imageName) for
if (Path.GetFileNameWithoutExtension(pictureEntry.Name) == content.contentid &&
allowedExtensions.Contains(Path.GetExtension(pictureEntry.Name)))
Also this line var imageName = content.contentid + ".jpg"; is innecesary as imageName didn't be used:
Related
I am using Renci.SSH and C# to connect to my Unix server from a Windows machine. My code works as expected when the directory contents are only files, but if the directory contains a folder, I get this
Renci.SshNet.Common.SshException: 'Failure'
This is my code, how can I update this to also download a directory (if exists)
private static void DownloadFile(string arc, string username, string password)
{
string fullpath;
string fp;
var options = new ProgressBarOptions
{
ProgressCharacter = '.',
ProgressBarOnBottom = true
};
using (var sftp = new SftpClient(Host, username, password))
{
sftp.Connect();
fp = RemoteDir + "/" + arc;
if (sftp.Exists(fp))
fullpath = fp;
else
fullpath = SecondaryRemoteDir + d + "/" + arc;
if (sftp.Exists(fullpath))
{
var files = sftp.ListDirectory(fullpath);
foreach (var file in files)
{
if (file.Name.ToLower().Substring(0, 1) != ".")
{
Console.WriteLine("Downloading file from the server...");
Console.WriteLine();
using (var pbar = new ProgressBar(100, "Downloading " + file.Name + "....", options))
{
SftpFileAttributes att = sftp.GetAttributes(fullpath + "/" + file.Name);
var fileSize = att.Size;
var ms = new MemoryStream();
IAsyncResult asyncr = sftp.BeginDownloadFile(fullpath + "/" + file.Name, ms);
SftpDownloadAsyncResult sftpAsyncr = (SftpDownloadAsyncResult)asyncr;
int lastpct = 0;
while (!sftpAsyncr.IsCompleted)
{
int pct = (int)((long)sftpAsyncr.DownloadedBytes / fileSize) * 100;
if (pct > lastpct)
for (int i = 1; i < pct - lastpct; i++)
pbar.Tick();
}
sftp.EndDownloadFile(asyncr);
Console.WriteLine("Writing File to disk...");
Console.WriteLine();
string localFilePath = "C:\" + file.Name;
var fs = new FileStream(localFilePath, FileMode.Create, FileAccess.Write);
ms.WriteTo(fs);
fs.Close();
ms.Close();
}
}
}
}
else
{
Console.WriteLine("The arc " + arc + " does not exist");
Console.WriteLine();
Console.WriteLine("Please press any key to close this window");
Console.ReadKey();
}
}
}
BeginDownloadFile downloads a file. You cannot use it to download a folder. For that you need to download contained files one by one.
The following example uses synchronous download (DownloadFile instead of BeginDownloadFile) for simplicity. After all, you are synchronously waiting for asynchronous download to complete anyway. To implement a progress bar with synchronous download, see Displaying progress of file download in a ProgressBar with SSH.NET.
public static void DownloadDirectory(
SftpClient sftpClient, string sourceRemotePath, string destLocalPath)
{
Directory.CreateDirectory(destLocalPath);
IEnumerable<SftpFile> files = sftpClient.ListDirectory(sourceRemotePath);
foreach (SftpFile file in files)
{
if ((file.Name != ".") && (file.Name != ".."))
{
string sourceFilePath = sourceRemotePath + "/" + file.Name;
string destFilePath = Path.Combine(destLocalPath, file.Name);
if (file.IsDirectory)
{
DownloadDirectory(sftpClient, sourceFilePath, destFilePath);
}
else
{
using (Stream fileStream = File.Create(destFilePath))
{
sftpClient.DownloadFile(sourceFilePath, fileStream);
}
}
}
}
}
I writing on an image converter. When I use parallel for each not all images are saved. Is the processing too fast for writing files on disk?
Here is my code:
private void convert()
{
Parallel.ForEach(source.GetFiles("*.tif"),
new ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount },
file =>
{
fileName = file.Name;
MagickImage image = new MagickImage(sourceFolderPath + "\\" + file);
image.ColorSpace = ColorSpace.XYZ;
image.GammaCorrect(2.4);
image.Write(destinationFolderPath + "\\" + fileName);
});
}
What did I do wrong?
Try disposing the image:
private void convert()
{
Parallel.ForEach(source.GetFiles("*.tif"),
new ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount },
file =>
{
fileName = file.Name;
using (MagickImage image = new MagickImage(sourceFolderPath + "\\" + file))
{
image.ColorSpace = ColorSpace.XYZ;
image.GammaCorrect(2.4);
image.Write(destinationFolderPath + "\\" + fileName);
}
});
}
I want copy file in my app to a folder with FileSavePicker. My Code:
var fileSavePicker = new FileSavePicker();
fileSavePicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
var filedb = new[] { ".db" };
fileSavePicker.FileTypeChoices.Add("DB", filedb);
fileSavePicker.SuggestedFileName = "BACKUPDB" + System.DateTime.Now.Day + "-" + System.DateTime.Now.Month + "-" + System.DateTime.Now.Year;
//var pathDB = Path.Combine(ApplicationData.Current.LocalFolder.Path, "file.db");
try
{
StorageFile file = await ApplicationData.Current.LocalFolder.GetFileAsync("file.db");
StorageFile localfile = await fileSavePicker.PickSaveFileAsync();
fileSavePicker.SuggestedSaveFile = file;
if (file != null)
{
Debug.WriteLine("file Exists!!");
var fileToSave = await fileSavePicker.PickSaveFileAsync();
....
but my saved file has size 0.
I found how to save text files but my file not is text.
You can use CopyAndReplaceAsync method to copy your local file to the chosen file.
var fileSavePicker = new Windows.Storage.Pickers.FileSavePicker();
fileSavePicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
var filedb = new[] { ".db" };
fileSavePicker.FileTypeChoices.Add("DB", filedb);
fileSavePicker.SuggestedFileName = "BACKUPDB" + System.DateTime.Now.Day + "-" + System.DateTime.Now.Month + "-" + System.DateTime.Now.Year;
//var pathDB = Path.Combine(ApplicationData.Current.LocalFolder.Path, "file.db");
try
{
StorageFile file = await ApplicationData.Current.LocalFolder.GetFileAsync("file.db");
StorageFile localfile = await fileSavePicker.PickSaveFileAsync();
if (file != null)
{
Debug.WriteLine("file Exists!!");
await file.CopyAndReplaceAsync(localfile);
}
}
catch(Exception ex)
{
Debug.WriteLine(ex);
}
I'm trying to scroll through images in my app, but I'm having trouble figuring out how to populate my list. The images are named using numbers from 1.jpg upwards. If anyone could help it would be great.
async private void Exec()
{
// Get the file location.
StorageFolder appFolder = Windows.ApplicationModel.Package.Current.InstalledLocation;
string myImageFolder = (appFolder.Path + "\\Assets\\Images");
int imageNumber = 1;
List<Uri> fileList = new List<Uri>();
foreach (var fileItem in fileList)
{
string imageFileName = imageNumber + ".jpg";
Uri uri = new Uri(myImageFolder + "/" + imageFileName);
fileList.Add(uri);
image.Source = new BitmapImage(new Uri(uri.ToString()));
await Task.Delay(TimeSpan.FromSeconds(1));
imageNumber++;
}
}
UPDATE
I have tried to create a workaround and do this without the foreach statement but its crashing when testing if the next file exists: :(
async private void Exec()
{
// Get the file location.
string root = Windows.ApplicationModel.Package.Current.InstalledLocation.Path;
string path = root + #"\Assets\Images";
StorageFolder appFolder = await StorageFolder.GetFolderFromPathAsync(path);
int imageNumber = 1;
int test = imageNumber;
do
{
string imageFileName = imageNumber + ".jpg";
Uri uri = new Uri(path + "\\" + imageFileName);
image.Source = new BitmapImage(new Uri(uri.ToString()));
await Task.Delay(TimeSpan.FromSeconds(1));
test = imageNumber + 1;
imageNumber++;
string testFile = test + ".jpg";
Uri uri1 = new Uri(path + "\\" + testFile);
if (await appFolder.TryGetItemAsync(uri1.ToString()) != null)
{
test = 99999;
}
}
while (test != 99999);
}
Your list does not contain any items. Your foreach will never run, as there will be no entries in your list.
You need to go through all paths in myImageFolder-root and add those uris to the list, then you can just use them in a foreach to create images and set their source, for every uri in the list.
Also imageNumber is un-needed then as you will have the URIs.
Prep the list of URIs first, by traversing the folder. Then modify the existing foreach to use those to build image objects.
Also, refrain from adding to a collection WHILE iterating it...
I have this working, and not a single foreach was required :D Thanks #Richard Eriksson
async private void Exec()
{
// Get the file location.
string root = Windows.ApplicationModel.Package.Current.InstalledLocation.Path;
string path = root + #"\Assets\Images";
StorageFolder appFolder = await StorageFolder.GetFolderFromPathAsync(path);
int imageNumber = 1;
int test = imageNumber;
do
{
string imageFileName = imageNumber + ".jpg";
Uri uri = new Uri(path + "\\" + imageFileName);
image.Source = new BitmapImage(new Uri(uri.ToString()));
await Task.Delay(TimeSpan.FromSeconds(1));
test = imageNumber + 1;
imageNumber++;
string testFile = test + ".jpg";
if (await appFolder.TryGetItemAsync(testFile) != null)
{
test = 99999;
}
else
{
test = 1;
}
}
while (test == 99999);
}
I have created these functions which I described in the question. However I think the way I did it is not the optimal way of doing it.
[HttpPost]
public ActionResult Create(FormCollection collection, string schooljaarparam, FlatONASAanbieder foa) {
if (ModelState.IsValid) {
// var r = new List<ViewDataUploadFilesResult>();
foreach (string file in Request.Files) {
HttpPostedFileBase hpf = Request.Files[file] as HttpPostedFileBase;
if (hpf.ContentLength == 0)
continue;
//extensie nakijken. jpg, png, jpeg, of GIF.
if (MvcApplication.isImage(hpf.FileName)) {
//Image img = new Image();
string savedFileName = Path.Combine(
AppDomain.CurrentDomain.BaseDirectory + "uploads\\ONAS\\",
Path.GetFileName(hpf.FileName));
FileInfo fi = new FileInfo(savedFileName);
int i = 1;
while (fi.Exists) {
fi = new FileInfo(savedFileName.Substring(0, savedFileName.Length - Path.GetFileName(savedFileName).Length) + Path.GetFileNameWithoutExtension(savedFileName) + " (" + i++ + ") " + Path.GetExtension(savedFileName));
}
savedFileName = fi.DirectoryName + "\\" + fi.Name;
hpf.SaveAs(savedFileName);
using (Image Img = Image.FromFile(savedFileName)) {
//Size ThumbNailSize = NewImageSize(Img.Height, Img.Width, 79);
Size NewSize = VerkleinMaxHoogte(Img.Size, 79);
using (Image ImgThnail = new Bitmap(Img, NewSize.Width, NewSize.Height)) {
//string ss = savedFileName.Substring(0, savedFileName.Length - Path.GetFileName(savedFileName).Length) + Path.GetFileNameWithoutExtension(savedFileName) + "-thumb" + Path.GetExtension(savedFileName);
ImgThnail.Save(savedFileName + ".tmp", Img.RawFormat);
ImgThnail.Dispose();
}
Img.Dispose();
}
System.IO.File.Delete(savedFileName);
FileInfo f = new FileInfo(savedFileName + ".tmp");
f.MoveTo(savedFileName);
} else {
ModelState.AddModelError("ONAS_Logo", "Het geuploadde bestand is geen afbeelding. ");
}
//r.Add(new ViewDataUploadFilesResult() {
// Name = savedFileName,
// Length = hpf.ContentLength
//});
}
}
// return View("UploadedFiles", r);
return View();
}
[NonAction]
public Size VerkleinMaxHoogte(Size orig, double height) {
double tempval = height / orig.Height;
return new Size(Convert.ToInt32(tempval * orig.Width), Convert.ToInt32(height));
}
in global.asax
public static bool isImage(string s) {
if (s.EndsWith(".jpg", true, null) || s.EndsWith(".jpeg", true, null) || s.EndsWith(".gif", true, null) || s.EndsWith(".png", true, null)) {
return true;
}
return false;
}
so the way I do it:
I get the file from the browser
I check if it is an Image
I check if the file exists, and if so, change the filename accordingly
I save the file on disk (IO, slow)
I open the file as an image
I calculate the width and height with the VerkleinMaxHoogte method
I create the thumbnail and save it with a tmp extension
I delete the original file
I rename the thumbnail to the original file name (this is what I want)
How do I do it faster?
You can always use HttpPostedFile.InputStream and Image.FromStream method to combine #4 & #5. This will also eliminate #8 & #9.