I generated three picture from wikipedia api.Now I want to store it in my current directory. with the following code I can successfully create folder with name.But it saves only one image, the last one. I am trying a lot. But could not fix how to save three images accordingly
public static void Load_Image1(string name1, string name2, string name3,string LocationName)
{
var startPath = Application.StartupPath;
string Imagefolder = Path.Combine(startPath, "Image");
string subImageFolder = Path.Combine(Imagefolder, LocationName);
System.IO.Directory.CreateDirectory(subImageFolder);
//string Jpeg = Path.Combine(Environment.CurrentDirectory, subImageFolder);
List<PictureBox> pictureBoxes = new List<PictureBox>();
pictureBoxes.Add(Image1);
pictureBoxes.Add(Image2);
pictureBoxes.Add(Image3);
using (var wc = new System.Net.WebClient())
{
var uri = ("https://en.wikipedia.org/w/api.php?action=query&prop=imageinfo&format=json&iiprop=url&iiurlwidth=400&titles="+name1+"|"+name2+"|"+name3);
var response = wc.DownloadString(new Uri(uri));
var responseJson = JsonConvert.DeserializeObject<RootObject>(response);
List<string> urls = new List<string>();
foreach (KeyValuePair<string, Pageval> entry in responseJson.query.pages)
{
var url = entry.Value.imageinfo.First().thumburl;
urls.Add(url);
var hash = uri.GetHashCode();
string Jpeg = Path.Combine(Environment.CurrentDirectory, subImageFolder);
var path = Path.Combine(Jpeg, hash.ToString("X") + ".jpg");
wc.DownloadFile(url, path);
}
for (int i = 0; i < pictureBoxes.Count; i++)
{
Image1.SizeMode = PictureBoxSizeMode.StretchImage;
Image2.SizeMode = PictureBoxSizeMode.StretchImage;
Image3.SizeMode = PictureBoxSizeMode.StretchImage;
pictureBoxes[i].Load(urls[i]);
var hash = uri.GetHashCode();
string Jpeg = Path.Combine(Environment.CurrentDirectory, subImageFolder);
var path = Path.Combine(Jpeg, hash.ToString("X") + ".jpg");
wc.DownloadFile(urls[i], path);
}
}
}
}
You are downloading all images to the same filename on the disk - causing the first two images to be overwritten by the last one.
The problem is that your base file name is based on
var hash = uri.GetHashCode();
This returns the same value since it's based on the url of all 3 images.
Change to:
var hash = url.GetHashCode();
you actually save all the pictures, but with the same name, that's why only the last remains in the filesystem (you keep overwriting the images). You should use a unique identifier in your variable path that allows you to distinguish the images, saving them with different names to avoid overwriting
public static void Load_Image1(string name1, string name2, string name3,string LocationName)
{
var startPath = Application.StartupPath;
string Imagefolder = Path.Combine(startPath, "Image");
string subImageFolder = Path.Combine(Imagefolder, LocationName);
System.IO.Directory.CreateDirectory(subImageFolder);
//string Jpeg = Path.Combine(Environment.CurrentDirectory, subImageFolder);
List<PictureBox> pictureBoxes = new List<PictureBox>();
pictureBoxes.Add(Image1);
pictureBoxes.Add(Image2);
pictureBoxes.Add(Image3);
using (var wc = new System.Net.WebClient())
{
var uri = ("https://en.wikipedia.org/w/api.php?action=query&prop=imageinfo&format=json&iiprop=url&iiurlwidth=400&titles="+name1+"|"+name2+"|"+name3);
var response = wc.DownloadString(new Uri(uri));
var responseJson = JsonConvert.DeserializeObject<RootObject>(response);
List<string> urls = new List<string>();
foreach (KeyValuePair<string, Pageval> entry in responseJson.query.pages)
{
var url = entry.Value.imageinfo.First().thumburl;
urls.Add(url);
var hash = url.GetHashCode();
string Jpeg = Path.Combine(Environment.CurrentDirectory, subImageFolder);
var path = Path.Combine(Jpeg, hash.ToString("X") + ".jpg");
wc.DownloadFile(url, path);
}
for (int i = 0; i < pictureBoxes.Count; i++)
{
Image1.SizeMode = PictureBoxSizeMode.StretchImage;
Image2.SizeMode = PictureBoxSizeMode.StretchImage;
Image3.SizeMode = PictureBoxSizeMode.StretchImage;
pictureBoxes[i].Load(urls[i]);
}
}
}
}
Related
I have refereed to the other examples on this website, but found a major difference in my method. (Please be patient)
I am trying to iterate over a directory of files and upload each file as an attachment and associate to a user story.
I am only able to attach 1 file for a user story as of now.
I see that every attachment has to be encoded to a base 64 string and it must have a the size in bytes.
Here is my code so far:
public void createUsWithAttachmentList(string workspace, string project, string userStoryName, string userStoryDescription)
{
//authentication
this.EnsureRallyIsAuthenticated();
//DynamicJSONObject for AttachmentContent
DynamicJsonObject myAttachmentContent = new DynamicJsonObject();
//Length calculated from Base64String converted back
int imageNumberBytes = 0;
//Userstory setup
DynamicJsonObject toCreate = new DynamicJsonObject();
toCreate["Workspace"] = workspace;
toCreate["Project"] = project;
toCreate["Name"] = userStoryName;
toCreate["Description"] = userStoryDescription;
//Trying to get a list of all the file paths within a given directory, this directory would contain .png files that need to be associated to a user story.
string[] attachmentPath = Directory.GetFiles("C:\\Users\\user\\Desktop\\RallyAttachments");
This foreach loop is confusing. I am trying to iterate over each file in the directory in order to convert it into a base64 string, and at the same time acquire the number of bytes for each file as an int.
foreach (string fileName in attachmentPath)
{
Image myImage = Image.FromFile(fileName);
string imageBase64String = imageToBase64(myImage, System.Drawing.Imaging.ImageFormat.Png);
imageNumberBytes = Convert.FromBase64String(imageBase64String).Length;
//I am stuck here to be exact because there are multiple imageBase64Strings due to the collection of files located inside the directory. AND the below line is wrong because I have a list of imageBase64Strings that were generated from iterating through the string[] attachmentPath.
myAttachmentContent[RallyField.content] = imageBase64String;
}
try
{
//create user story
CreateResult createUserStory = _api.Create(RallyField.attachmentContent, myAttachmentContent);
//create attachment
CreateResult myAttachmentContentCreateResult = _api.Create(RallyField.attachmentContent, myAttachmentContent);
String myAttachmentContentRef = myAttachmentContentCreateResult.Reference;
//DynamicJSONObject for Attachment Container
//I assume I would need a separate container for each file in my directory containing the attachments.
DynamicJsonObject myAttachment = new DynamicJsonObject();
myAttachment["Artifact"] = createUserStory.Reference;
myAttachment["Content"] = myAttachmentContentRef;
myAttachment["Name"] = "AttachmentFromREST.png";
myAttachment["Description"] = "Email Attachment";
myAttachment["ContentType"] = "image/png";
myAttachment["Size"] = imageNumberBytes;
//create & associate the attachment
CreateResult myAttachmentCreateResult = _api.Create(RallyField.attachment, myAttachment);
Console.WriteLine("Created User Story: " + createUserStory.Reference);
}
catch (WebException e)
{
Console.WriteLine(e.Message);
}
}
Note: I am planning on extending this method to support multiple file types, and I thing I would need to get the file type of each file in the directory and proceed accordingly.
Any ideas on how to go about writing this?
You've got all the parts implemented- we just need to move it around a little bit. Create the story once at the beginning, and then each time through the loop make a new AttachmentContent and a new Attachment for each file.
public void createUsWithAttachmentList(string workspace, string project, string userStoryName, string userStoryDescription)
{
//authentication
this.EnsureRallyIsAuthenticated();
//Userstory setup
DynamicJsonObject toCreate = new DynamicJsonObject();
toCreate["Workspace"] = workspace;
toCreate["Project"] = project;
toCreate["Name"] = userStoryName;
toCreate["Description"] = userStoryDescription;
//Create the story first
try
{
//create user story
CreateResult createUserStory = _api.Create(RallyField.userStory, toCreate);
//now loop over each file
string[] attachmentPath = Directory.GetFiles("C:\\Users\\user\\Desktop\\RallyAttachments");
foreach (string fileName in attachmentPath)
{
//DynamicJSONObject for AttachmentContent
DynamicJsonObject myAttachmentContent = new DynamicJsonObject();
Image myImage = Image.FromFile(fileName);
string imageBase64String = imageToBase64(myImage, System.Drawing.Imaging.ImageFormat.Png);
int imageNumberBytes = Convert.FromBase64String(imageBase64String).Length;
myAttachmentContent[RallyField.content] = imageBase64String;
//create the AttachmentConent
CreateResult myAttachmentContentCreateResult = _api.Create(RallyField.attachmentContent, myAttachmentContent);
String myAttachmentContentRef = myAttachmentContentCreateResult.Reference;
//create an Attachment to associate to story
DynamicJsonObject myAttachment = new DynamicJsonObject();
myAttachment["Artifact"] = createUserStory.Reference;
myAttachment["Content"] = myAttachmentContentRef;
myAttachment["Name"] = "AttachmentFromREST.png";
myAttachment["Description"] = "Email Attachment";
myAttachment["ContentType"] = "image/png";
myAttachment["Size"] = imageNumberBytes;
//create & associate the attachment
CreateResult myAttachmentCreateResult = _api.Create(RallyField.attachment, myAttachment);
}
}
catch (WebException e)
{
Console.WriteLine(e.Message);
}
}
I am writing a pdf to word converter which works perfectly fine for me. But I want to be able to convert more than one file.
What happens now is that it read the first file and does the convert process.
public static void PdfToImage()
{
try
{
Application application = null;
application = new Application();
var doc = application.Documents.Add();
string path = #"C:\Users\Test\Desktop\pdfToWord\";
foreach (string file in Directory.EnumerateFiles(path, "*.pdf"))
{
using (var document = PdfiumViewer.PdfDocument.Load(file))
{
int pagecount = document.PageCount;
for (int index = 0; index < pagecount; index++)
{
var image = document.Render(index, 200, 200, true);
image.Save(#"C:\Users\chnikos\Desktop\pdfToWord\output" + index.ToString("000") + ".png", ImageFormat.Png);
application.Selection.InlineShapes.AddPicture(#"C:\Users\chnikos\Desktop\pdfToWord\output" + index.ToString("000") + ".png");
}
string getFileName = file.Substring(file.LastIndexOf("\\"));
string getFileWithoutExtras = Regex.Replace(getFileName, #"\\", "");
string getFileWihtoutExtension = Regex.Replace(getFileWithoutExtras, #".pdf", "");
string fileName = #"C:\Users\Test\Desktop\pdfToWord\" + getFileWihtoutExtension;
doc.PageSetup.PaperSize = WdPaperSize.wdPaperA4;
foreach (Microsoft.Office.Interop.Word.InlineShape inline in doc.InlineShapes)
{
if (inline.Height > inline.Width)
{
inline.ScaleWidth = 250;
inline.ScaleHeight = 250;
}
}
doc.PageSetup.TopMargin = 28.29f;
doc.PageSetup.LeftMargin = 28.29f;
doc.PageSetup.RightMargin = 30.29f;
doc.PageSetup.BottomMargin = 28.29f;
application.ActiveDocument.SaveAs(fileName, WdSaveFormat.wdFormatDocument);
doc.Close();
}
}
I thought that with my foreach that problem should not occur. And yes there are more than one pdf in this folder
The line
var doc = application.Documents.Add();
is outside the foreach loop. So you only create a single word document for all your *.pdf files.
Move the above line inside the foreach loop to add a new word document for each *.pdf file.
I am trying to create text file which should contain a city name and interesting places name of that city. For this, initially I create a text file with City name. My City_list.txt file looks like this-
Flensburg
Kiel
Lübeck
Neumünster
Heide
Geesthacht
Husum
Elmshorn
Pinneberg
Wedel
...... many more
Now My next work is,by using the city name get all external links exist in Wikipedia article. So , I create a list to get all the city name so that it can create place name one after other. But my code is not working.I create the place list for Wedel, for the last one only. But not for flensburg to wedel. I know there is one looping problem, But could not get the point where should I modify my work.
My code is as follows-
public void PoiListFromWiki()
{
var startPath = Application.StartupPath;
string folderName = Path.Combine(startPath, "POI_List");
System.IO.Directory.CreateDirectory(folderName);
string fileName = "POI.txt";
var path = Path.Combine(folderName, fileName);
List<string> ReadFile = File.ReadAllLines(#"I:\TouristPlace\TouristPlace\bin\Debug\CityList\POI_list.txt", Encoding.GetEncoding("windows-1252")).ToList();
foreach (string line in ReadFile)
{
Dictionary<string, string> cities = new Dictionary<string, string>();
using (var client = new HttpClient())
{
var response = client.GetAsync("https://en.wikipedia.org/w/api.php?action=query&list=geosearch&gsradius=10000&gspage=" + WebUtility.UrlEncode(line) + "&gslimit=500&gsprop=type|name|dim|country|region|globe&format=json").Result;
if (response.IsSuccessStatusCode)
{
var responseContent = response.Content;
string responseString = responseContent.ReadAsStringAsync().Result;
var obj = JsonConvert.DeserializeObject<RootObject>(responseString).query.geosearch.Select(a => a.title).ToList(); //NulReferanceException error occurd
List<string> places = new List<string>();
foreach (var item in obj)
{
places.Add(item);
}
cities[line] = string.Join(";", places);
var output = line + ";" + cities[line];
File.WriteAllText(path, output); //here is problem
}
}
}
}
My Expected Result is
Flensburg;place1;place2..
Kiel;Place1;Place2..
Lübeck;Place1;Place2..
But With my code I got only
Lübeck;Place1;Place2..
You write the output file again and again in each loop but WriteAllText overwrite everytime the previous data with the new one. But you could do a lot better than appending to the previous text. Just use a StringBuilder to store the text while you get it and write just one time after the exit from the loop.
Here the significant changes to make to your current code....
public void PoiListFromWiki()
{
StringBuilder results = new StringBuilder();
.....
foreach (string line in ReadFile)
{
Dictionary<string, string> cities = new Dictionary<string, string>();
using (var client = new HttpClient())
{
....
cities[line] = string.Join(";", places);
results.AppendLine(line + ";" + cities[line]);
}
}
File.WriteAllText(path, results.ToString());
}
File.WrtieAllText overwrites the file. You need to use File.AppendAllText.
public void PoiListFromWiki()
{
var startPath = Application.StartupPath;
string folderName = Path.Combine(startPath, "POI_List");
System.IO.Directory.CreateDirectory(folderName);
string fileName = "POI.txt";
var path = Path.Combine(folderName, fileName);
List<string> ReadFile = File.ReadAllLines(#"I:\TouristPlace\TouristPlace\bin\Debug\CityList\POI_list.txt", Encoding.GetEncoding("windows-1252")).ToList();
foreach (string line in ReadFile)
{
Dictionary<string, string> cities = new Dictionary<string, string>();
using (var client = new HttpClient())
{
var response = client.GetAsync("https://en.wikipedia.org/w/api.php?action=query&list=geosearch&gsradius=10000&gspage=" + WebUtility.UrlEncode(line) + "&gslimit=500&gsprop=type|name|dim|country|region|globe&format=json").Result;
if (response.IsSuccessStatusCode)
{
var responseContent = response.Content;
string responseString = responseContent.ReadAsStringAsync().Result;
var obj = JsonConvert.DeserializeObject<RootObject>(responseString).query.geosearch.Select(a => a.title).ToList(); //NulReferanceException error occurd
List<string> places = new List<string>();
foreach (var item in obj)
{
places.Add(item);
}
cities[line] = string.Join(";", places);
var output = line + ";" + cities[line] + "\r\n";
if (!File.Exists(path))
{
File.WriteAllText(path, output); //here is problem
}
else
{
File.AppendAllText(path, output);
}
}
}
}
}
Try it:
public void PoiListFromWiki()
{
var startPath = Application.StartupPath;
string folderName = Path.Combine(startPath, "POI_List");
System.IO.Directory.CreateDirectory(folderName);
string fileName = "POI.txt";
var path = Path.Combine(folderName, fileName);
var output="";
List<string> ReadFile = File.ReadAllLines(#"I:\TouristPlace\TouristPlace\bin\Debug\CityList\POI_list.txt", Encoding.GetEncoding("windows-1252")).ToList();
foreach (string line in ReadFile)
{
Dictionary<string, string> cities = new Dictionary<string, string>();
using (var client = new HttpClient())
{
var response = client.GetAsync("https://en.wikipedia.org/w/api.php?action=query&list=geosearch&gsradius=10000&gspage=" + WebUtility.UrlEncode(line) + "&gslimit=500&gsprop=type|name|dim|country|region|globe&format=json").Result;
if (response.IsSuccessStatusCode)
{
var responseContent = response.Content;
string responseString = responseContent.ReadAsStringAsync().Result;
var obj = JsonConvert.DeserializeObject<RootObject>(responseString).query.geosearch.Select(a => a.title).ToList(); //NulReferanceException error occurd
List<string> places = new List<string>();
foreach (var item in obj)
{
places.Add(item);
}
cities[line] = string.Join(";", places);
output += line + ";" + cities[line]+"/r/n"; //always add new info in string, then write it all in file
File.WriteAllText(path, output);
}
}
}
}
I've a folder named testPhotos with some images. Based on the image creation date, I want to create a new folder by image creation year and then move the image to that folder.
For example, testPhotos has image named 01.jpg which was created on 2011. So I want to create a folder named 2011 inside testPhotos like testPhotos\2011 and move image to that folder. While doing this I am getting The process cannot access the file because it is being used by another process. error while moving image from one folder to another.
Code:
private void button1_Click(object sender, EventArgs e)
{
var creationDate = new DateTime();
var dateList = new List<String>();
var fileName = String.Empty;
var sourceFolder = #"C:\My Stuff\Test Porjects\testPhotos";
String[] images = Directory.GetFiles(sourceFolder);
if (images.Count() > 0)
{
foreach (var imagePath in images)
{
fileName = Path.GetFileName(imagePath);
creationDate = GetDateTakenFromImage(imagePath);
var date = creationDate.GetDateTimeFormats()[5].Replace("-", "/");
if (!String.IsNullOrEmpty(date))
{
var year = date.Substring(0, 4);
var destinationFolder = sourceFolder + "\\" + year;
if (!Directory.Exists(destinationFolder))
{
Directory.CreateDirectory(destinationFolder);
String fileToMove = sourceFolder+ "\\" + fileName;
String moveTo = destinationFolder + "\\" + fileName;
File.Move(fileToMove, moveTo);
}
}
}
}
}
private DateTime GetDateTakenFromImage(string path)
{
Image myImage = Image.FromFile(path);
PropertyItem propItem = myImage.GetPropertyItem(36867);
string dateTaken = new Regex(":").Replace(Encoding.UTF8.GetString(propItem.Value), "-", 2);
return DateTime.Parse(dateTaken);
}
Any ideas?
This looks like a missing dispose on the image, try with the following:
private DateTime GetDateTakenFromImage(string path)
{
using (Image myImage = Image.FromFile(path))
{
PropertyItem propItem = myImage.GetPropertyItem(36867);
string dateTaken = new Regex(":").Replace(Encoding.UTF8.GetString(propItem.Value), "-", 2);
return DateTime.Parse(dateTaken);
}
}
Hello I have signature like this:
which is encoded to a DataUrl specifically this string:
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAADICAYAAADGFbfiAAAYlElEQVR4Xu2dC8w1R1nHQSCIgIKVGLmoiLciFwUs... (long string)"
What i want to do is Convert this DataUrl to an PNG Image, and save the image to the device, this is what i am doing so far:
if (newItem.FieldType == FormFieldType.Signature)
{
if (newItem.ItemValue != null)
{
//string completeImageName = Auth.host + "/" + li[i];
string path;
string filename;
string stringName = newItem.ItemValue;
var base64Data = Regex.Match(stringName, #"data:image/(?<type>.+?),(?<data>.+)").Groups["data"].Value;
var binData = Convert.FromBase64String(base64Data);
path = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
filename = Path.Combine(path, base64Data);
if (!File.Exists(filename))
{
using (var stream = new MemoryStream(binData))
{
//Code crashing here--------------------------
File.WriteAllBytes(filename, binData);
}
}
newItem.ItemValue = filename;
}
}
App.Database.SaveReportItem(newItem);
But my code is making my application to crash specifically in this line:
File.WriteAllBytes(filename, binData);
The sample I am using as reference (Link) is using a PictureBox but with Xamarin there is no use of a pictureBox.
Any Ideas?
As #SLaks mentioned I didn't need a MemoryStream, the problem with my code was the path and the filename for further help this is the working code:
if (newItem.FieldType == FormFieldType.Signature)
{
if (newItem.ItemValue != null)
{
//string completeImageName = Auth.host + "/" + li[i];
string path;
string filename;
string stringName = newItem.ItemValue;
var base64Data = Regex.Match(stringName, #"data:image/(?<type>.+?),(?<data>.+)").Groups["data"].Value;
var binData = Convert.FromBase64String(base64Data);
path = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
//filename = Path.Combine(path, base64Data.Replace(#"/", string.Empty));
long milliseconds = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
string fileName = "Sn" + milliseconds.ToString() + ".PNG";
filename = Path.Combine(path, fileName);
if (!File.Exists(filename))
{
//using (var stream = new MemoryStream(binData))
//{
File.WriteAllBytes(filename, binData);
//}
}
newItem.ItemValue = filename;
}
}
App.Database.SaveReportItem(newItem);
And the image showed:
I just cleaned Mario's code and fine tuned regex:
public string SaveDataUrlToFile(string dataUrl, string savePath)
{
var matchGroups = Regex.Match(dataUrl, #"^data:((?<type>[\w\/]+))?;base64,(?<data>.+)$").Groups;
var base64Data = matchGroups["data"].Value;
var binData = Convert.FromBase64String(base64Data);
System.IO.File.WriteAllBytes(savePath, binData);
return savePath;
}