Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 5 years ago.
Improve this question
I have found various code and libraries for editing Exif.
But they are only lossless when the image width and height is multiple of 16.
I am looking for a library (or even a way to do it myself) to edit just the Exif portion in a JPEG file (or add Exif data if it doesn't exist yet), leaving the other data unmodified. Isn't that possible?
So far I could only locate the Exif portion (starts with 0xFFE1) but I don't understand how to read the data.
Here are the specifications for the Exif interchange format, if you plan to code your own library for editing tags.
http://www.exif.org/specifications.html
Here's a library written in Perl that meets your needs that you may be able to learn from:
http://www.sno.phy.queensu.ca/~phil/exiftool/
Here's a decent .NET library for Exif evaluation from The Code Project:
http://www.codeproject.com/KB/graphics/exiftagcol.aspx
You can do this without any external lib:
// Create image.
Image image1 = Image.FromFile("c:\\Photo1.jpg");
// Get a PropertyItem from image1. Because PropertyItem does not
// have public constructor, you first need to get existing PropertyItem
PropertyItem propItem = image1.GetPropertyItem(20624);
// Change the ID of the PropertyItem.
propItem.Id = 20625;
// Set the new PropertyItem for image1.
image1.SetPropertyItem(propItem);
// Save the image.
image1.Save("c:\\Photo1.jpg", ImageFormat.Jpg);
List of all possible PropertyItem ids (including exif) you can found here.
Update: Agreed, this method will re-encode image on save. But I have remembered another method, in WinXP SP2 and later there is new imaging components added - WIC, and you can use them to lossless write metadate - How-to: Re-encode a JPEG Image with Metadata.
exiv2net library (a .NET wrapper on top of exiv2) may be what you're looking for.
I wrote a small test where I compress one file many times to see the quality degradation and you can see it in the third-fourth compression, which is very bad.
But luckily, if you always use same QualityLevel with JpegBitmapEncoder there is no degradation.
In this example I rewrite keywords 100x in metadata and the quality seems not to change.
private void LosslessJpegTest() {
var original = "d:\\!test\\TestInTest\\20150205_123011.jpg";
var copy = original;
const BitmapCreateOptions createOptions = BitmapCreateOptions.PreservePixelFormat | BitmapCreateOptions.IgnoreColorProfile;
for (int i = 0; i < 100; i++) {
using (Stream originalFileStream = File.Open(copy, FileMode.Open, FileAccess.Read)) {
BitmapDecoder decoder = BitmapDecoder.Create(originalFileStream, createOptions, BitmapCacheOption.None);
if (decoder.CodecInfo == null || !decoder.CodecInfo.FileExtensions.Contains("jpg") || decoder.Frames[0] == null)
continue;
BitmapMetadata metadata = decoder.Frames[0].Metadata == null
? new BitmapMetadata("jpg")
: decoder.Frames[0].Metadata.Clone() as BitmapMetadata;
if (metadata == null) continue;
var keywords = metadata.Keywords == null ? new List<string>() : new List<string>(metadata.Keywords);
keywords.Add($"Keyword {i:000}");
metadata.Keywords = new ReadOnlyCollection<string>(keywords);
JpegBitmapEncoder encoder = new JpegBitmapEncoder {QualityLevel = 80};
encoder.Frames.Add(BitmapFrame.Create(decoder.Frames[0], decoder.Frames[0].Thumbnail, metadata,
decoder.Frames[0].ColorContexts));
copy = original.Replace(".", $"_{i:000}.");
using (Stream newFileStream = File.Open(copy, FileMode.Create, FileAccess.ReadWrite)) {
encoder.Save(newFileStream);
}
}
}
}
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I have 400 sequence images.
I want to create from them video file ( clip .. mpeg )
I download the 'AForge.NET' and i try to look into it to see if it possible - but i don't fine any way to do it.
How can i do it ?
Look up the documentation, find the VideoFileWriter Class, look at it's members, see the WriteVideoFrame method(s), read the line: "Write new video frame into currently opened video file.". Bingo. Half way there.
If you can't connect the dots when reading the methods' signature (WriteVideoFrame(Bitmap)) or don't understand how to use the Open() overloads or Close() method (why wouldn't you, the last two are pretty common for File I/O) you can always Google "VideoFileWriter WriteVideoFrame example", find code, go from there. The meat of the function there is:
VideoFileWriter writer = new VideoFileWriter();
writer.Open("myfile.avi", width, height, 25, VideoCodec.MPEG4, 1000000);
// ... here you'll need to load your bitmaps
writer.WriteVideoFrame(image);
}
writer.Close();
So something like this should probably work:
using (VideoFileWriter writer = new VideoFileWriter())
{
writer.Open(#"d:\myfile.avi", 640, 480, 25, VideoCodec.MPEG4);
foreach (var file in Directory.GetFiles(#"d:\foo\bar", "*.jpg"))
{
writer.WriteVideoFrame(Bitmap.FromFile(file) as Bitmap);
}
writer.Close();
}
Which, with a few minutes of fiddling around, gave me something like this:
var size = new Size(1600, 1200); // The desired size of the video
var fps = 25; // The desired frames-per-second
var codec = VideoCodec.MPEG4; // Which codec to use
var destinationfile = #"d:\myfile.avi"; // Output file
var srcdirectory = #"d:\foo\bar"; // Directory to scan for images
var pattern = "*.jpg"; // Files to look for in srcdirectory
var searchoption = SearchOption.TopDirectoryOnly; // Search Top Directory Only or all subdirectories (recursively)?
using (var writer = new VideoFileWriter()) // Initialize a VideoFileWriter
{
writer.Open(destinationfile, size.Width, size.Height, fps, codec); // Start output of video
foreach (var file in Directory.GetFiles(srcdirectory, pattern, searchoption)) // Iterate files
{
using (var original = (Bitmap)Image.FromFile(file)) // Read bitmap
using (var resized = new Bitmap(original, size)) // Resize if necessary
writer.WriteVideoFrame(resized); // Write frame
}
writer.Close(); // Close VideoFileWriter
} // Dispose VideoFileWriter
This resizes images; should not all images in the sequence be the same. If they are you can skip that step simply by changing
using (var original = (Bitmap)Image.FromFile(file)) // Read bitmap
using (var resized = new Bitmap(original, size)) // Resize if necessary
writer.WriteVideoFrame(resized); // Write frame
to:
using (var mybitmap = (Bitmap)Image.FromFile(file)) // Read bitmap
writer.WriteVideoFrame(mybitmap); // Write frame
Also make sure you add the correct using statements; you will, at a minimum, need the following for above examples:
using AForge.Video.FFMPEG;
using System.Drawing;
using System.IO;
Also you'll need to reference the DLL's as described here:
... you should have created a project, added a reference to the AForge.Video.FFMPEG library, set the target platform to x86 and the target framework version to 3.5 or lower now. If so, it can go on.
... we need a few more dlls from the AForge archive. You can find these in the folder “Externals\ffmpeg” inside the AForge archive. All files in this folder have to be copied to the output folder of your Visual Studio project. (After we changed the target architecture this now should be “YourProjectFolder\bin\x86\Debug”.)
If it still doesn't work then tell us what happens, exact error messages etc.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 8 years ago.
Improve this question
I was just wondering if anyone has experience reading barcodes from a pdf file. I googled and found this bytescout reader and used the program like this
Reader barcodeReader = new Reader();
barcodeReader.BarcodeTypesToFind.Code39 = true;
Console.WriteLine("Reading barcode(s) from PDF");
FoundBarcode[] barcodes = barcodeReader.ReadFrom("Sample.pdf");
foreach (FoundBarcode barcode in barcodes)
Console.WriteLine("Found barcode with type '{0}' and value '{1}'", barcode.Type, barcode.Value);
This doesn't output any barcodes.
Please suggest any other library I could use?
DataMatrix is a C# library that can decode barcodes from image files and I believe it can read them from PDFs too. Here is an example of usage:
private string DecodeText(string sFileName)
{
DmtxImageDecoder decoder = new DmtxImageDecoder();
System.Drawing.Bitmap oBitmap = new System.Drawing.Bitmap(sFileName);
List<string> oList = decoder.DecodeImage(oBitmap);
StringBuilder sb = new StringBuilder();
sb.Length = 0;
foreach (string s in oList)
{
sb.Append(s);
}
return sb.ToString();
}
You pass in an image filename and it will decode the barcode and return the string. If DataMatrix does not read from PDFs, then you'll have to also download iTextSharp which is a library for manipulating PDFs. Using iTextSharp, you can extract the barcode from the PDF, save it as an image, then use the function above to interpret the barcode.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking us to recommend or find a tool, library or favorite off-site resource are off-topic for Stack Overflow as they tend to attract opinionated answers and spam. Instead, describe the problem and what has been done so far to solve it.
Closed 9 years ago.
Improve this question
I am trying to save a PDF file by saving the data from the FDF into a PDFTemplate, in my WPF application.
So, the situation is like this. I have a PDFTemplate.pdf which serves as a template and has placeholders (or fields). Now I generate this FDF file pro-grammatically, which in turn contain all the field names required for the PDFTemplate to be filled in. Also, this FDF contains the file path for the PDFTemaplte also, so that on opening, it knows which PDF to use.
Now, when try and double click on the FDF, it open the Adober Acrobat Reader and displays the PDFTemplate with the data filled in. But I can't save this file using the File menu, as it says this file will be saved without the data.
I would like to know if it is possible to import the FDF data into PDF and save it without using a thrid party component.
Also, if it is very difficult to do this, what would be the possible solution in terms of a free library that would be able to do it?
I just realized that iTextSharp is not free for commercial applications.
I have been able to achieve this using another library PDFSharp.
It is somewhat similar to how iTextSharp works except for some places where in iTextSharp is better and easier to use. I am posting the code in case someone would want to do something similar:
//Create a copy of the original PDF file from source
//to the destination location
File.Copy(formLocation, outputFileNameAndPath, true);
//Open the newly created PDF file
using (var pdfDoc = PdfSharp.Pdf.IO.PdfReader.Open(
outputFileNameAndPath,
PdfSharp.Pdf.IO.PdfDocumentOpenMode.Modify))
{
//Get the fields from the PDF into which the data
//is supposed to be inserted
var pdfFields = pdfDoc.AcroForm.Fields;
//To allow appearance of the fields
if (pdfDoc.AcroForm.Elements.ContainsKey("/NeedAppearances") == false)
{
pdfDoc.AcroForm.Elements.Add(
"/NeedAppearances",
new PdfSharp.Pdf.PdfBoolean(true));
}
else
{
pdfDoc.AcroForm.Elements["/NeedAppearances"] =
new PdfSharp.Pdf.PdfBoolean(true);
}
//To set the readonly flags for fields to their original values
bool flag = false;
//Iterate through the fields from PDF
for (int i = 0; i < pdfFields.Count(); i++)
{
try
{
//Get the current PDF field
var pdfField = pdfFields[i];
flag = pdfField.ReadOnly;
//Check if it is readonly and make it false
if (pdfField.ReadOnly)
{
pdfField.ReadOnly = false;
}
pdfField.Value = new PdfSharp.Pdf.PdfString(
fdfDataDictionary.Where(
p => p.Key == pdfField.Name)
.FirstOrDefault().Value);
//Set the Readonly flag back to the field
pdfField.ReadOnly = flag;
}
catch (Exception ex)
{
throw new Exception(ERROR_FILE_WRITE_FAILURE + ex.Message);
}
}
//Save the PDF to the output destination
pdfDoc.Save(outputFileNameAndPath);
pdfDoc.Close();
}
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 7 years ago.
Improve this question
I'm looking for a free to use c# library/code to create barcodes. Secifically I need to be able to create QR-Code type barcodes. I'm looking for free to use (Open Source or just Free, etc.) not pay to use.
Take a look QRCoder - pure C# open source QR code generator.
Can be used in three lines of code
QRCodeGenerator qrGenerator = new QRCodeGenerator();
QRCodeGenerator.QRCode qrCode = qrGenerator.CreateQrCode(textBoxQRCode.Text, QRCodeGenerator.ECCLevel.Q);
pictureBoxQRCode.BackgroundImage = qrCode.GetGraphic(20);
ZXing is an open source project that can detect and parse a number of different barcodes. It can also generate QR-codes. (Only QR-codes, though).
There are a number of variants for different languages: ActionScript, Android (java), C++, C#, IPhone (Obj C), Java ME, Java SE, JRuby, JSP. Support for generating QR-codes comes with some of those: ActionScript, Android, C# and the Java variants.
Generate QR Code Image in ASP.NET Using Google Chart API
Google Chart API returns an image in response to a URL GET or POST request.
All the data required to create the graphic is included in the URL, including the image type and size.
var url = string.Format("http://chart.apis.google.com/chart?cht=qr&chs={1}x{2}&chl={0}", txtCode.Text, txtWidth.Text, txtHeight.Text);
WebResponse response = default(WebResponse);
Stream remoteStream = default(Stream);
StreamReader readStream = default(StreamReader);
WebRequest request = WebRequest.Create(url);
response = request.GetResponse();
remoteStream = response.GetResponseStream();
readStream = new StreamReader(remoteStream);
System.Drawing.Image img = System.Drawing.Image.FromStream(remoteStream);
img.Save("D:/QRCode/" + txtCode.Text + ".png");
response.Close();
remoteStream.Close();
readStream.Close();
txtCode.Text = string.Empty;
txtWidth.Text = string.Empty;
txtHeight.Text = string.Empty;
lblMsg.Text = "The QR Code generated successfully";
Click here for complete source code to download
Demo of application for free QR Code generator using C#
You can look at Open Source QR Code Library or messagingtoolkit-qrcode. I have not used either of them so I can not speak of their ease to use.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 7 years ago.
Improve this question
Looking at other posts for this could not find an adequate solution that for my needs. Trying to just get the first page of a pdf document as a thumbnail. This is to be run as a server application so would not want to write out a pdf document to file to then call a third application that reads the pdf to generate the image on disk.
doc = new PDFdocument("some.pdf");
page = doc.page(1);
Image image = page.image;
Thanks.
Matthew Ephraim released an open source wrapper for Ghostscript that sounds like it does what you want and is in C#.
Link to Source Code: https://github.com/mephraim/ghostscriptsharp
Link to Blog Posting: http://www.mattephraim.com/blog/2009/01/06/a-simple-c-wrapper-for-ghostscript/
You can make a simple call to the GeneratePageThumb method to generate a thumbnail (or use GeneratePageThumbs with a start and end page number to generate thumbnails for multiple seperate pages, with each page being a seperate output file), default file format is jpeg but you can change it, and many other options, by using the alternate GenerateOutput method call and specify options such as file format, page size, etc...
I think that Windows API Code pack for Microsoft .NET framework might do the trick easiest. What it can is to generate the same thumbnail that Windows Explorer does (and that is first page), and you can chose several sizes, they go up to 1024x1024, so it should be enough. It is quite simple, just create ShellObject.FromParsingName(filepath) and find its Thumbnail subclass.
The problem might be what your server is. This works on Windows 7, Windows Vista and I guess Windows Server 2008. Also, Windows Explorer must be able to show thumbnails on that machine. The easiest way to insure that is to install Adobe Reader. If all of this is not a problem, I think that this is the most elegant way.
UPDATE: Adobe Reader has dropped support for thumbnails in the recent versions so its legacy versions must be used.
UPDATE2: According to comment from Roberto, you can still use latest version of Adobe Reader if you turn on thumbnails option in Edit - Preferences - General.
Download PDFLibNet and use the following code
public void ConvertPDFtoJPG(string filename, String dirOut)
{
PDFLibNet.PDFWrapper _pdfDoc = new PDFLibNet.PDFWrapper();
_pdfDoc.LoadPDF(filename);
for (int i = 0; i < _pdfDoc.PageCount; i++)
{
Image img = RenderPage(_pdfDoc, i);
img.Save(Path.Combine(dirOut, string.Format("{0}{1}.jpg", i,DateTime.Now.ToString("mmss"))));
}
_pdfDoc.Dispose();
return;
}
public Image RenderPage(PDFLibNet.PDFWrapper doc, int page)
{
doc.CurrentPage = page + 1;
doc.CurrentX = 0;
doc.CurrentY = 0;
doc.RenderPage(IntPtr.Zero);
// create an image to draw the page into
var buffer = new Bitmap(doc.PageWidth, doc.PageHeight);
doc.ClientBounds = new Rectangle(0, 0, doc.PageWidth, doc.PageHeight);
using (var g = Graphics.FromImage(buffer))
{
var hdc = g.GetHdc();
try
{
doc.DrawPageHDC(hdc);
}
finally
{
g.ReleaseHdc();
}
}
return buffer;
}
I used to do this kind of stuff with imagemagick (Convert) long ago.
There is a .Net Wrapper for that, maybe it's worth checking out :
http://imagemagick.codeplex.com/releases/view/30302
http://www.codeproject.com/KB/cs/GhostScriptUseWithCSharp.aspx
This works very well. The only dependencies are GhostScript's gsdll32.dll (you need to download GhostScript separately to get this, but there is no need to have GhostScript installed in your production environment), and PDFSharp.dll which is included in the project.