So, I am making a project in Windows Forms in which I have to change image formats. I found different solutions for that, such as:
convert tiff to jpg format
c# convert image formats to jpg.
And these solutions are working, but they all have one similarity:
image.Save(path,ImageFormat.Jpeg)
In this code I am saving the image in one directory. What I want to do is to save this formatted images with Savefiledialog. But in this case, when I call Savefiledialog, I need to write "image" name and format. If I don't write the format, it creates a simple file without extension. I want to automatically save the file in the specified format. So how to do that?
I would write something simple like this:
// might make sense to make this a property under the relevant class
Dictionary<string, ImageFormat> mapOfExtensions =
new Dictionary<string, ImageFormat>
{
{".jpg", ImageFormat.Jpeg},
{".jpeg", ImageFormat.Jpeg},
{".png", ImageFormat.Png}
};
var ext = Path.GetExtension(path);
// safety check - make sure the file extension is what we expect...
if (!mapOfExtensions.Contains(ext))
{
// probably would make sense to throw an error, log a message, etc.
return;
}
image.Save(path,mapOfExtensions[ext]);
Related
I'm kind of confused as to the way C# saves bitmaps. I currently use this statement to save a bitmap to (virtually) any extension (.ico, .dds, etc.).
Bitmap.Save(FileName);
This actually works for any extension I choose, but I'm having doubts it's saving in correct format. Reason for said doubts is because I found another article here,
How to save Bitmap as icon?, which does so like:
// Create a Bitmap object from an image file.
Bitmap bmp = new Bitmap(sFn);
// Get an Hicon for myBitmap.
IntPtr Hicon = bmp.GetHicon();
// Create a new icon from the handle.
Icon newIcon = Icon.FromHandle(Hicon);
//Write Icon to File Stream
System.IO.FileStream fs = new System.IO.FileStream(destFileName, System.IO.FileMode.OpenOrCreate);
newIcon.Save(fs);
Which is obviously way different. So two questions:
How can/does the first approach work if the second is the "correct" way?
Would I need to customize save properties for each individual extension I wish to support or is the first method sufficient for any extension?
The proper way would be to use the original Bitmap.Save(Filename) but you are missing the ImageFormat variable which will basically do the actualy Conversion from an image obejct ot the specified format.
Currently the way you are using it results in a file named "somefile.somextension" but does not have the actual contents of an icon object for example.
best way would be to use :
Bitmap.Save(String, ImageFormat)
for example, to save a .ico file :
Bitmap.Save(String, System.Drawing.Imaging.ImageFormat.Icon)
Hope this helps, good luck.
I have created sort of a cross language Random Texture Generator using C# and Java to help design backgrounds for an iPhone app that I am designing. In short, my program first generates a random array of bytes to represent the texture in the Java portion, then the C# portion takes the bytes and creates a Bitmap which is saved to an image file (Jpeg,Png,etc). I have gotton my program to run perfectly except that when I save the Bitmap to a file it doesn't save with an extension, So I can't view the image after it is created. I have this line of code:
bitMap.Save("testImage", System.Drawing.Imaging.ImageFormat.Jpeg);
which should save the bitmap with a Jpeg extension, but it saves it with no extension. Could anyone help me with this conundrum?
If you're saving the bitmap with a jpeg extension (.jpg or .jpeg), you need to match the file format to the file extension.
It seems you want to support multiple extensions. To do this, I'd use the following:
string extension = "";
switch (format)
{
case (System.Drawing.Imaging.ImageFormat.Jpeg);
extension = ".jpg"; break;
.
.
.
}
bitMap.Save("testImage"+extension, System.Drawing.Imaging.ImageFormat.Jpeg);
Where you create an extension based on the desired file format, then use that extension to save the file.
The first parameter of Bitmap.Save method in MSDN defined as
filename
Type: System.String
A string that contains the name of the file to which to save this Image.
You must use this method as
bitMap.Save("testImage.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
See documentation for more info.
I hooked into the question located at "Replace image in word doc using OpenXML". I noticed that there are several ImagePartType types. Is there any easy "built in" way to determine which type a specific image should be other than going by it's extension? The ImagePartType enum is also used in PowerPoint as is alot of the WordProcessingML structures.,
For instance,
ImagePartType.Bmp on image1.bmp
ImagePartType.Emf on image1.emf
ImagePartType.Gif on image1.gif
ImagePartType.Icon on image1.ico
ImagePartType.Jpeg on image1.jpeg or image1.jpg
ImagePartType.Pcx on image1.pcx
ImagePartType.Png on image1.png
ImagePartType.Tiff on image1.tiff or image1.tif
ImagePartType.Wmf on image1.wmf
There is not - because you can have filename.png which is actually a bmp file and it all works fine. The only way to know for sure is to read the actual bitmap file and see what format it is in.
You can do this either by loading it into an Image class, or just read the first couple of bytes and look for the signature of each of the formats.
I'm doing this:
private void LoadSoundFile()
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
if (openFileDialog1.FileName.EndsWith(".mp3"))
{
txtFileName.Text = openFileDialog1.FileName;
}
else
{
MessageBox.Show("Currently Musicality only supports MP3 files.", "Unsupported file chosen.");
}
}
}
Is there a better way of checking file types or am I doing it the right way?
Having the .mp3 extension doesn't mean it is an mp3, but not having it is an (acceptable) indication that it isn't.
At some point you will call some API to play the file, and it will fail. When it does, you know it's not a playable file. So make sure you handle that with some decent UI too.
Your question seems to ask if the right way to check if a file is MP3 is to look at the end of the filename. As others have said, the answer to that is no. Matt Warren's post can help you if you want to look into the file to see if it is actually mp3 format.
But your comment on Eran Betzalel's answer makes me wonder if you are asking generally whether the right way to check a file extension is to use String.EndsWith().
One thing to notice is that EndsWith(string) is case-sensitive, so the results of:
EndsWith("mp3")
EndsWith("Mp3")
EndsWith("MP3")
and
EndsWith("mP3")
don't all give the same answer. A better test might be:
if (Path.GetExtension(openFileDialog1.FileName).ToLower() == "mp3")
if all you care about is the file extension and not the file contents.
If you actually want to analyse the file (to check if it really is a .mp3) you'll need to look at the specification so you parse it correctly. Here is a good place to start and there is some more info here. This article on the CodeProject goes even further and extracts ID3 tags as well as the header.
This will be better than just checking that the extension is ".mp3", but it's a lot of extra work so it has to be worthwhile.
It really depends on the nature of your program. I think that if you are not developing a security related application, then you can use the simple extension check.
No, because file extension is simply an indicator, it is not a reliable guide to what the file is or contains.
I can name i music file as mySong.zzz and it will still play in Winamp. When you load it you should sample the start of the file to see if it really is an mp3.
You can also set a filter on your open file dialog so that it only allows the user to select mp3 files:
openFileDialog1.Filter = "mp3|*.mp3|All Files|*.*";
I guess the proper way to actually check if it's an MP3 file (this requires that the file be opened) is to look for "magic numbers", sequences of bytes within the binary data that always occur. In this case, you can use the ID3 tag's magic number: ID3v1 tags are stored in the last 128 bytes of the file starting with the bytes "TAG" (hexadecimal "544147"), while ID3v2 tags are stored at the beginning of the file, so the first 3 bytes of the file are "ID3" (hexadecimal "494433"). I don't know if the MP3 frames themselves have simple magic numbers like this. Obviously, this method requires the file to be opened, which could make a scan of a large number of files slower.
If you want to be sure, load the file with this lib http://sourceforge.net/projects/id3dotnet/ it will fail with an exception if not an mp3. Simply create an Id3.Net.Mp3File with filename or stream in constructor an see if it throws an exception
Today i'm cutting video at work (yea me!), and I came across a strange video format, an MOD file format with an companion MOI file.
I found this article online from the wiki, and I wanted to write a file format handler, but I'm not sure how to begin.
I want to write a file format handler to read the information files, has anyone ever done this and how would I begin?
Edit:
Thanks for all the suggestions, I'm going to attempt this tonight, and I'll let you know. The MOI files are not very large, maybe 5KB in size at most (I don't have them in front of me).
You're in luck in that the MOI format at least spells out the file definition. All you need to do is read in the file and interpret the results based on the file definition.
Following the definition, you should be able to create a class that could read and interpret a file which returns all of the file format definitions as properties in their respective types.
Reading the file requires opening the file and generally reading it on a byte-by-byte progression, such as:
using(FileStream fs = File.OpenRead(path-to-your-file)) {
while(true) {
int b = fs.ReadByte();
if(b == -1) {
break;
}
//Interpret byte or bytes here....
}
}
Per the wiki article's referenced PDF, it looks like someone already reverse engineered the format. From the PDF, here's the first entry in the format:
Hex-Address: 0x00
Data Type: 2 Byte ASCII
Value (Hex): "V6"
Meaning: Version
So, a simplistic implementation could pull the first 2 bytes of data from the file stream and convert to ASCII, which would provide a property value for the Version.
Next entry in the format definition:
Hex-Address: 0x02
Data Type: 4 Byte Unsigned Integer
Value (Hex):
Meaning: Total size of MOI-file
Interpreting the next 4 bytes and converting to an unsigned int would provide a property value for the MOI file size.
Hope this helps.
If the files are very large and just need to be streamed in, I would create a new reader object that uses an unmanagedmemorystream to read the information in.
I've done a lot of different file format processing like this. More recently, I've taken to making a lot of my readers more functional where reading tends to use 'yield return' to return read only objects from the file.
However, it all depends on what you want to do. If you are trying to create a general purpose format for use in other applications or create an API, you probably want to conform to an existing standard. If however you just want to get data into your own application, you are free to do it however you want. You could use a binaryreader on the stream and construct the information you need within your app, or get the reader to return objects representing the contents of the file.
The one thing I would recommend. Make sure it implements IDisposable and you wrap it in a using!