I am using itextsharp for extracting content from PDF using c# as follow
public static string GetTextFromAllPages(String pdfPath)
{
PdfReader reader = new PdfReader(pdfPath);
StringWriter output = new StringWriter();
for (int i = 1; i <= reader.NumberOfPages; i++)
output.WriteLine(PdfTextExtractor.GetTextFromPage(reader, i, new SimpleTextExtractionStrategy()));
return output.ToString();
}
Now change I want in this code whenever there are images in PDF it should include an image tag (<img>) in the content.
I tried with the extracting images alone and I am able to do it but not sure how to merge these two codes together to make extracted content consist with img tag also .
Extraction code of image as follow :
private static List<System.Drawing.Image> ExtractImages(String PDFSourcePath)
{
//string res = GetTextFromAllPages(PDFSourcePath);
//File.WriteAllText(#"d:\blobfile\blobfileresult.txt", res);
List<System.Drawing.Image> ImgList = new List<System.Drawing.Image>();
iTextSharp.text.pdf.RandomAccessFileOrArray RAFObj = null;
iTextSharp.text.pdf.PdfReader PDFReaderObj = null;
iTextSharp.text.pdf.PdfObject PDFObj = null;
iTextSharp.text.pdf.PdfStream PDFStremObj = null;
try
{
RAFObj = new iTextSharp.text.pdf.RandomAccessFileOrArray(PDFSourcePath);
PDFReaderObj = new iTextSharp.text.pdf.PdfReader(RAFObj, null);
if (PDFReaderObj.IsOpenedWithFullPermissions)
{
Console.WriteLine("this is a test");
}
for (int i = 0; i <= PDFReaderObj.XrefSize - 1; i++)
{
PDFObj = PDFReaderObj.GetPdfObject(i);
if ((PDFObj != null) && PDFObj.IsStream())
{
PDFStremObj = (iTextSharp.text.pdf.PdfStream)PDFObj;
iTextSharp.text.pdf.PdfObject subtype = PDFStremObj.Get(iTextSharp.text.pdf.PdfName.SUBTYPE);
if ((subtype != null) && subtype.ToString() == iTextSharp.text.pdf.PdfName.IMAGE.ToString())
// if ((subtype != null) && subtype.ToString() == iTextSharp.text.pdf.PdfName.CCITTFAXDECODE.ToString())
{
byte[] bytes = iTextSharp.text.pdf.PdfReader.GetStreamBytesRaw((iTextSharp.text.pdf.PRStream)PDFStremObj);
if ((bytes != null))
{
try
{
System.IO.MemoryStream MS = new System.IO.MemoryStream(bytes);
MS.Position = 0;
System.Drawing.Image ImgPDF = System.Drawing.Image.FromStream(MS);
ImgList.Add(ImgPDF);
}
catch (Exception e)
{
Console.WriteLine("Exception in extract: " + e);
}
}
}
}
}
PDFReaderObj.Close();
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
return ImgList;
}
Related
Hi have a Xamarin Android project using C#. Currently I am using await CrossMedia.Current.PickPhotoAsync() method to upload image. However, it did not provide a tickbox beside the images for me to select multiple. How can I manage to select multiple images and upload together?
You could implement it by yourself.
1.Add these methods to your MainActivity.cs file
public static int OPENGALLERYCODE = 100;
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
//If we are calling multiple image selection, enter into here and return photos and their filepaths.
if (requestCode == OPENGALLERYCODE && resultCode == Result.Ok)
{
List<string> images = new List<string>();
if (data != null)
{
//Separate all photos and get the path from them all individually.
ClipData clipData = data.ClipData;
if (clipData != null)
{
for (int i = 0; i < clipData.ItemCount; i++)
{
ClipData.Item item = clipData.GetItemAt(i);
Android.Net.Uri uri = item.Uri;
var path = GetRealPathFromURI(uri);
if (path != null)
{
images.Add(path);
}
}
}
else
{
Android.Net.Uri uri = data.Data;
var path = GetRealPathFromURI(uri);
if (path != null)
{
images.Add(path);
}
}
}
}
}
/// <summary>
/// Get the real path for the current image passed.
/// </summary>
public String GetRealPathFromURI(Android.Net.Uri contentURI)
{
try
{
ICursor imageCursor = null;
string fullPathToImage = "";
imageCursor = ContentResolver.Query(contentURI, null, null, null, null);
imageCursor.MoveToFirst();
int idx = imageCursor.GetColumnIndex(MediaStore.Images.ImageColumns.Data);
if (idx != -1)
{
fullPathToImage = imageCursor.GetString(idx);
}
else
{
ICursor cursor = null;
var docID = DocumentsContract.GetDocumentId(contentURI);
var id = docID.Split(':')[1];
var whereSelect = MediaStore.Images.ImageColumns.Id + "=?";
var projections = new string[] { MediaStore.Images.ImageColumns.Data };
cursor = ContentResolver.Query(MediaStore.Images.Media.InternalContentUri, projections, whereSelect, new string[] { id }, null);
if (cursor.Count == 0)
{
cursor = ContentResolver.Query(MediaStore.Images.Media.ExternalContentUri, projections, whereSelect, new string[] { id }, null);
}
var colData = cursor.GetColumnIndexOrThrow(MediaStore.Images.ImageColumns.Data);
cursor.MoveToFirst();
fullPathToImage = cursor.GetString(colData);
}
return fullPathToImage;
}
catch (Exception ex)
{
Toast.MakeText(Xamarin.Forms.Forms.Context, "Unable to get path", ToastLength.Long).Show();
}
return null;
}
2.invoked the following in the specific Activity which you want to open the picker
public void OpenGallery()
{
try
{
var imageIntent = new Intent(Intent.ActionPick);
imageIntent.SetType("image/*");
imageIntent.PutExtra(Intent.ExtraAllowMultiple, true);
imageIntent.SetAction(Intent.ActionGetContent);
this.StartActivityForResult(Intent.CreateChooser(imageIntent, "Select photo"), OPENGALLERYCODE);
Toast.MakeText(this, "Tap and hold to select multiple photos.", ToastLength.Short).Show();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
Toast.MakeText(this, "Error. Can not continue, try again.", ToastLength.Long).Show();
}
}
void ClearFileDirectory()
{
var directory = new Java.IO.File(Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryPictures), ImageHelpers.collectionName).Path.ToString();
if (Directory.Exists(directory))
{
var list = Directory.GetFiles(directory, "*");
if (list.Length > 0)
{
for (int i = 0; i < list.Length; i++)
{
File.Delete(list[i]);
}
}
}
}
//collectionName is the name of the folder in your Android Pictures directory.
public static readonly string collectionName = "TmpPictures";
public string SaveFile(byte[] imageByte, string fileName)
{
var fileDir = new Java.IO.File(Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryPictures), collectionName);
if (!fileDir.Exists())
{
fileDir.Mkdirs();
}
var file = new Java.IO.File(fileDir, fileName);
System.IO.File.WriteAllBytes(file.Path, imageByte);
return file.Path;
}
public string CompressImage(string path)
{
byte[] imageBytes;
//Get the bitmap.
var originalImage = BitmapFactory.DecodeFile(path);
//Set imageSize and imageCompression parameters.
var imageSize = .86;
var imageCompression = 67;
//Resize it and then compress it to Jpeg.
var width = (originalImage.Width * imageSize);
var height = (originalImage.Height * imageSize);
var scaledImage = Bitmap.CreateScaledBitmap(originalImage, (int)width, (int)height, true);
using (MemoryStream ms = new MemoryStream())
{
scaledImage.Compress(Bitmap.CompressFormat.Jpeg, imageCompression, ms);
imageBytes = ms.ToArray();
}
originalImage.Recycle();
originalImage.Dispose();
GC.Collect();
return SaveFile(imageBytes, Guid.NewGuid().ToString());
}
I'm using this code to modify a pdf tmeplate to add specific details to it,
private static byte[] GeneratePdfFromPdfFile(byte[] file, string landingPage, string code)
{
try
{
using (var ms = new MemoryStream())
{
using (var reader = new PdfReader(file))
{
using (var stamper = new PdfStamper(reader, ms))
{
string _embeddedURL = "http://" + landingPage + "/Default.aspx?code=" + code + "&m=" + eventCode18;
PdfAction act = new PdfAction(_embeddedURL);
stamper.Writer.SetOpenAction(act);
stamper.Close();
reader.Close();
return ms.ToArray();
}
}
}
}
catch(Exception ex)
{
File.WriteAllText(HttpRuntime.AppDomainAppPath + #"AttachmentException.txt", ex.Message + ex.StackTrace);
return null;
}
}
this Method is being called from this Method:
public static byte[] GenerateAttachment(AttachmentExtenstion type, string Contents, string FileName, string code, string landingPage, bool zipped, byte[] File = null)
{
byte[] finalVal = null;
try
{
switch (type)
{
case AttachmentExtenstion.PDF:
finalVal = GeneratePdfFromPdfFile(File, landingPage, code);
break;
case AttachmentExtenstion.WordX:
case AttachmentExtenstion.Word:
finalVal = GenerateWordFromDocFile(File, code, landingPage);
break;
case AttachmentExtenstion.HTML:
finalVal = GenerateHtmlFile(Contents, code, landingPage);
break;
}
return zipped ? _getZippedFile(finalVal, FileName) : finalVal;
}
catch(Exception ex)
{
return null;
}
}
and here is the main caller,
foreach (var item in Recipients)
{
//...
//....
item.EmailAttachment = AttachmentGeneratorEngine.GenerateAttachment(_type, "", item.AttachmentName, item.CMPRCode, _cmpTmp.LandingDomain, _cmpTmp.AttachmentZip.Value, _cmpTmp.getFirstAttachment(item.Language, item.DefaultLanguage));
}
The AttachmentGeneratorEngine.GenerateAttachment method is being called approx. 4k times, because I'm adding a specific PDF file from a PDF template for every element in my List.
recently I started having this exception:
Exception of type 'System.OutOfMemoryException' was thrown. at System.IO.MemoryStream.ToArray()
I already implemented IDisposible in the classes and and I made sure that all of them are being released.
Note: it was running before very smoothely and also I double checked the system's resources - 9 GB is used out of 16 GB, so I had enough memory available.
==========================================
Update:
Here is the code that loops through the list
public static bool ProcessGroupLaunch(string groupCode, int customerId, string UilangCode)
{
CampaignGroup cmpGList = GetCampaignGroup(groupCode, customerId, UilangCode)[0];
_campaigns = GetCampaigns(groupCode, customerId);
List<CampaignRecipientLib> Recipients = GetGroupRcipientsToLaunch(cmpGList.ID, customerId);
try
{
foreach (var item in _campaigns)
item.Details = GetCampaignDetails(item.CampaignId.Value, UilangCode);
Stopwatch stopWatch = new Stopwatch();
#region single-threaded ForEach
foreach (var item in Recipients)
{
CampaignLib _cmpTmp = _campaigns.FirstOrDefault(x => x.CampaignId.Value == item.CampaignId);
bool IncludeAttachment = _cmpTmp.IncludeAttachment ?? false;
bool IncludeAttachmentDoubleBarrel = _cmpTmp.IncludeAttachmentDoubleBarrel ?? false;
if (IncludeAttachment)
{
if (_cmpTmp.AttachmentExtension.ToLower().Equals("doc") || (_cmpTmp.AttachmentExtension.ToLower().Equals("docx")))
_type = AttachmentGeneratorEngine.AttachmentExtenstion.Word;
else if (_cmpTmp.AttachmentExtension.ToLower().Equals("ppt") || (_cmpTmp.AttachmentExtension.ToLower().Equals("pptx")))
_type = AttachmentGeneratorEngine.AttachmentExtenstion.PowePoint;
else if (_cmpTmp.AttachmentExtension.ToLower().Equals("xls") || (_cmpTmp.AttachmentExtension.ToLower().Equals("xlsx")))
_type = AttachmentGeneratorEngine.AttachmentExtenstion.Excel;
else if (_cmpTmp.AttachmentExtension.ToLower().Equals("pdf"))
_type = AttachmentGeneratorEngine.AttachmentExtenstion.PDF;
else if (_cmpTmp.AttachmentExtension.ToLower().Equals("html"))
_type = AttachmentGeneratorEngine.AttachmentExtenstion.HTML;
}
//set "recpient" details
item.EmailFrom = _cmpTmp.EmailFromPrefix + "#" + _cmpTmp.EmailFromDomain;
item.EmailBody = GetChangedPlaceHolders((_cmpTmp.getBodybyLangCode(string.IsNullOrEmpty(item.Language) ? item.DefaultLanguage : item.Language, item.DefaultLanguage)), item.ID, _cmpTmp.CustomerId.Value, _cmpTmp.CampaignId.Value);
if (item.EmailBody.Contains("[T-LandingPageLink]"))
{
//..
}
if (item.EmailBody.Contains("[T-FeedbackLink]"))
{
//..
}
if (item.EmailBody.Contains("src=\".."))
{
//..
}
//set flags to be used by the SMTP Queue and Scheduler
item.ReadyTobeSent = true;
item.PickupReady = false;
//add attachment to the recipient, if any.
if (IncludeAttachment)
{
item.AttachmentName = _cmpTmp.getAttachmentSubjectbyLangCode(string.IsNullOrEmpty(item.Language) ? item.DefaultLanguage : item.Language, item.DefaultLanguage) + "." + _cmpTmp.AttachmentExtension.ToLower();
try
{
if (_type == AttachmentGeneratorEngine.AttachmentExtenstion.PDF || _type == AttachmentGeneratorEngine.AttachmentExtenstion.WordX || _type == AttachmentGeneratorEngine.AttachmentExtenstion.Word)
item.EmailAttachment = AttachmentGeneratorEngine.GenerateAttachment(_type, "", item.AttachmentName, item.CMPRCode, _cmpTmp.LandingDomain, _cmpTmp.AttachmentZip.Value, _cmpTmp.getFirstAttachment(item.Language, item.DefaultLanguage));
else item.EmailAttachment = AttachmentGeneratorEngine.GenerateAttachment(_type, value, item.AttachmentName, item.CMPRCode, _cmpTmp.LandingDomain, _cmpTmp.AttachmentZip.Value);
item.AttachmentName = _cmpTmp.AttachmentZip.Value ? (_cmpTmp.getAttachmentSubjectbyLangCode(string.IsNullOrEmpty(item.Language) ? item.DefaultLanguage : item.Language, item.DefaultLanguage) + ".zip") :
_cmpTmp.getAttachmentSubjectbyLangCode(string.IsNullOrEmpty(item.Language) ? item.DefaultLanguage : item.Language, item.DefaultLanguage) + "." + _cmpTmp.AttachmentExtension.ToLower();
}
catch (Exception ex)
{
}
}
else
{
item.EmailAttachment = null;
item.AttachmentName = null;
}
}
#endregion
stopWatch.Stop();
bool res = WriteCampaignRecipientsLaunch(ref Recipients);
return res;
}
catch (Exception ex)
{
Recipients.ForEach(i => i.Dispose());
cmpGList.Dispose();
Recipients = null;
cmpGList = null;
return false;
}
finally
{
Recipients.ForEach(i => i.Dispose());
cmpGList.Dispose();
Recipients = null;
cmpGList = null;
}
}
Here is the code: This is the content of the main of a console
application, the code compiles and runs, the video is captured but not
the audio.
FFmpegBinariesHelper.RegisterFFmpegBinaries();
ffmpeg.av_register_all();
ffmpeg.avcodec_register_all();
ffmpeg.avformat_network_init();
AVFormatContext* context = ffmpeg.avformat_alloc_context();
int video_stream_index = 0;
ffmpeg.av_register_all();
ffmpeg.avcodec_register_all();
ffmpeg.avformat_network_init();
//open rtsp
if (ffmpeg.avformat_open_input(&context, "rtsp://user:pass#IPAddress/axis-media/media.amp?", null, null) != 0)
{
return ;
}
if (ffmpeg.avformat_find_stream_info(context, null) < 0)
{
return;
}
//search video stream
for (int i = 0; i < context->nb_streams; i++)
{
if (context->streams[i]->codec->codec_type == AVMediaType.AVMEDIA_TYPE_VIDEO)
video_stream_index = i;
}
AVPacket packet;
ffmpeg.av_init_packet(&packet);
//open output file
AVOutputFormat* fmt = ffmpeg.av_guess_format("mp4", null, null);
// AVFormatContext* oc = ffmpeg.avformat_alloc_context();
AVFormatContext* oc = null;
ffmpeg.avformat_alloc_output_context2(&oc, fmt, null, null);
oc->oformat = fmt;
ffmpeg.avio_open2(&oc->pb, "test.mp4", ffmpeg.AVIO_FLAG_WRITE, null, null);
AVStream* stream = null;
int cnt = 0;
//start reading packets from stream and write them to file
ffmpeg.av_read_play(context);//play RTSP
while (ffmpeg.av_read_frame(context, &packet) >= 0 && cnt < 1000)
{//read 100 frames
if (packet.stream_index == video_stream_index)
{//packet is video
if (stream == null)
{//create stream in file
stream = ffmpeg.avformat_new_stream(oc, context->streams[video_stream_index]->codec->codec);
ffmpeg.avcodec_copy_context(stream->codec, context->streams[video_stream_index]->codec);
stream->sample_aspect_ratio = context->streams[video_stream_index]->codec->sample_aspect_ratio;
ffmpeg.avformat_write_header(oc, null);
}
packet.stream_index = stream->id;
ffmpeg.av_interleaved_write_frame(oc, &packet);
cnt++;
}
ffmpeg.av_free_packet(&packet);
ffmpeg.av_init_packet(&packet);
}
ffmpeg.av_read_pause(context);
ffmpeg.av_write_trailer(oc);
ffmpeg.avio_close(oc->pb);
ffmpeg.avformat_free_context(oc);
I found the way to add the code for the audio, and now the audio is copying and in sync with the video. Here is the code:
AVFormatContext* ifcx = null;
AVCodecContext* v_iccx = null;
AVCodec* v_icodec = null;
AVStream* v_ist = null;
int v_index;
AVCodecContext* a_iccx = null;
AVCodec* a_icodec = null;
AVStream* a_ist = null;
int a_index;
DateTime timenow, timestart;
AVFormatContext* ofcx;
AVOutputFormat* ofmt;
AVStream* ost;
AVPacket packet;
string sFileInput;
string sFileOutput;
sFileInput = rtspUrl;
var startNumber = 0;
var filePrefix = "camera" + cameraId;
// create folder if not exist
if (!Directory.Exists(destinationFolder))
{
Directory.CreateDirectory(destinationFolder);
}
var files = Directory.GetFiles(destinationFolder, "*" + filePrefix + "*");
if (files.Any())
{
var lastFile = files.Last();
var temp = lastFile.Substring(lastFile.Length - 7, 3);
if (int.TryParse(temp, out startNumber))
{
startNumber++;
}
}
string NextFile = string.Format("{0}\\{1}-{2:000}.mp4", destinationFolder, filePrefix, startNumber);
//EventLog.WriteEntry(sSource, "Capturing " + NextFile );
sFileOutput = NextFile;
FFmpegBinariesHelper.RegisterFFmpegBinaries();
// Initialize library
ffmpeg.av_log_set_level(ffmpeg.AV_LOG_DEBUG);
ffmpeg.av_register_all();
ffmpeg.avcodec_register_all();
ffmpeg.avformat_network_init();
//
// Input
//
AVFormatContext** tmpIfcx = &ifcx;
var ts = new CancellationTokenSource();
CancellationToken ct = ts.Token;
var task = new Task<int>(() => Avformat_open_input_async(tmpIfcx, sFileInput),ct);
task.Start();
task.Wait(2000);
if (!task.IsCompleted)
{
ts.Cancel();
//EventLog.WriteEntry(sSource, "Waiting on task Avformat_open_input_async ", EventLogEntryType.Warning);
task.Wait(2000);
//EventLog.WriteEntry(sSource, "Timeout callling " + sFileInput, EventLogEntryType.Error);
return;
}
var result = task.Result;
//open rtsp
// ifcx = tmpIfcx;
if (result != 0)
{
EventLog.WriteEntry(sSource, "ERROR: Cannot open input file " + sFileInput, EventLogEntryType.Error);
return;
}
if (ffmpeg.avformat_find_stream_info(ifcx, null) < 0)
{
EventLog.WriteEntry(sSource, "ERROR: Cannot find stream info\n", EventLogEntryType.Error);
ffmpeg.avformat_close_input(&ifcx);
return;
}
//search video stream
v_index = -1;
a_index = -1;
for (int ix = 0; ix < ifcx->nb_streams; ix++)
{
if (ifcx->streams[ix]->codec->codec_type == AVMediaType.AVMEDIA_TYPE_VIDEO)
{
v_ist = ifcx->streams[ix];
v_icodec = ifcx->video_codec;
v_index = ix;
v_iccx = ifcx->streams[ix]->codec;
}
if (ifcx->streams[ix]->codec->codec_type == AVMediaType.AVMEDIA_TYPE_AUDIO)
{
a_ist = ifcx->streams[ix];
a_icodec = ifcx->video_codec;
a_index = ix;
a_iccx = ifcx->streams[ix]->codec;
}
}
if (v_index < 0)
{
EventLog.WriteEntry(sSource, "ERROR: Cannot find input video stream\n",EventLogEntryType.Error);
ffmpeg.avformat_close_input(&ifcx);
return;
}
//
// Output
//
//open output file
ofmt = ffmpeg.av_guess_format(null, sFileOutput, "mp4");
// ffmpeg.format
ofcx = ffmpeg.avformat_alloc_context();
ofcx->oformat = ofmt;
ffmpeg.avio_open(&ofcx->pb, sFileOutput, ffmpeg.AVIO_FLAG_WRITE);
// Create output stream
ost = ffmpeg.avformat_new_stream( ofcx, (AVCodec *) v_iccx->codec );
AVStream* a_ost = ffmpeg.avformat_new_stream(ofcx, (AVCodec*)a_iccx->codec);
//ost = ffmpeg.avformat_new_stream(ofcx, ifcx->video_codec);
ffmpeg.avcodec_copy_context(ost->codec, v_iccx);
ffmpeg.avcodec_copy_context(a_ost->codec, a_iccx);
ffmpeg.avcodec_open2(v_iccx, v_icodec, null);
ffmpeg.avcodec_open2(a_iccx, a_icodec, null);
// Assume r_frame_rate is accurate
var avRational = new AVRational();
avRational.den = ost->r_frame_rate.den * 2;
avRational.num = ost->r_frame_rate.num ;
var aaRational = new AVRational();
aaRational.den = a_ost->r_frame_rate.den ;
aaRational.num = a_ost->r_frame_rate.num ;
ost->r_frame_rate = avRational;
ost->avg_frame_rate = ost->r_frame_rate;
ost->time_base = av_inv_q(ost->r_frame_rate);
ost->codec->time_base = ost->time_base;
a_ost->r_frame_rate = aaRational;
a_ost->avg_frame_rate = a_ost->r_frame_rate;
a_ost->time_base = av_inv_q(a_ost->r_frame_rate);
a_ost->codec->time_base = a_ost->time_base;
ffmpeg.avformat_write_header(ofcx, null);
//start reading packets from stream and write them to file
ffmpeg.av_dump_format(ifcx, 0, ifcx->filename.ToString(), 0);
ffmpeg.av_dump_format(ofcx, 0, ofcx->filename.ToString(), 1);
timestart = timenow = DateTime.Now;
ffmpeg.av_init_packet(&packet);
if (segmentLength == 0)
segmentLength = 15;
var dateToEnd = DateTime.Now.AddMinutes(segmentLength);
//EventLog.WriteEntry(sSource, "date to end capture " + dateToEnd.ToString());
while ( (dateToEnd - DateTime.Now).TotalMinutes > 0 && IsCapturing)
{
if (endDateTime.HasValue && DateTime.Compare(DateTime.Now, endDateTime.Value) >= 0)
{
ffmpeg.av_packet_unref(&packet);
ffmpeg.av_init_packet(&packet);
IsCapturing = false;
break;
}
int readFrame = -1;
try
{
readFrame = ffmpeg.av_read_frame(ifcx, &packet);
}
catch(Exception ex)
{
EventLog.WriteEntry(sSource, $"Error av_read_frame {ex.ToString()}", EventLogEntryType.Error);
break;
}
if (readFrame < 0)
{
EventLog.WriteEntry(sSource, "reafFrame < 0 " + NextFile, EventLogEntryType.Error);
ffmpeg.av_packet_unref(&packet);
ffmpeg.av_init_packet(&packet);
break;
}
if (packet.stream_index == v_index)
{ //packet is video
packet.stream_index = v_ist->index;
ffmpeg.av_interleaved_write_frame(ofcx, &packet);
}
if (packet.stream_index == a_index)
{ //packet is audio
SetPacketProperties(&packet, a_iccx, a_ist);
ffmpeg.av_interleaved_write_frame(ofcx, &packet);
}
ffmpeg.av_packet_unref(&packet);
ffmpeg.av_init_packet(&packet);
}
ffmpeg.av_read_pause(ifcx);
ffmpeg.av_write_trailer(ofcx);
ffmpeg.avio_close(ofcx->pb);
ffmpeg.avformat_free_context(ofcx);
ffmpeg.avformat_network_deinit();
private unsafe void SetPacketProperties(AVPacket* packet, AVCodecContext* codecContext, AVStream* stream)
{
packet->pts = ffmpeg.av_rescale_q_rnd(packet->pts, codecContext->time_base, stream->time_base, AVRounding.AV_ROUND_NEAR_INF | AVRounding.AV_ROUND_PASS_MINMAX);
packet->dts = ffmpeg.av_rescale_q_rnd(packet->dts, codecContext->time_base, stream->time_base, AVRounding.AV_ROUND_NEAR_INF | AVRounding.AV_ROUND_PASS_MINMAX);
packet->duration = (int)ffmpeg.av_rescale_q(packet->duration, codecContext->time_base, stream->time_base);
packet->stream_index = stream->index;
}
I need to extract one image for page of a pdf,i have a code extracted from another question in stackoverflow to extract images from a pdf, and some times Works all perfect, but other times not extract the images in the order that i hope(first page it will be the first image) and the first image correspond to the first page of the pdf file, this is the code:
private static int WriteImageFile(string pdf, string path)
{
int nfotos = 0;
try
{
// Get a List of Image
List<System.Drawing.Image> ListImage = ExtractImages(pdf);
nfotos = ListImage.Count;
for (int i = 0; i < ListImage.Count; i++)
{
try
{
ListImage[i].Save(path+ "\\Image" + i + ".bmp", System.Drawing.Imaging.ImageFormat.Bmp);
}
catch (Exception e)
{ MessageBox.Show(e.Message); }
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
return nfotos;
}
private static List<System.Drawing.Image> ExtractImages(String PDFSourcePath)
{
List<System.Drawing.Image> ImgList = new List<System.Drawing.Image>();
iTextSharp.text.pdf.RandomAccessFileOrArray RAFObj = null;
iTextSharp.text.pdf.PdfReader PDFReaderObj = null;
iTextSharp.text.pdf.PdfObject PDFObj = null;
iTextSharp.text.pdf.PdfStream PDFStremObj = null;
try
{
RAFObj = new iTextSharp.text.pdf.RandomAccessFileOrArray(PDFSourcePath);
PDFReaderObj = new iTextSharp.text.pdf.PdfReader(RAFObj, null);
Form1 formulario = new Form1();
for (int i = 0; i <= PDFReaderObj.XrefSize - 1; i++)
{
PDFObj = PDFReaderObj.GetPdfObject(i);
if ((PDFObj != null) && PDFObj.IsStream())
{
PDFStremObj = (iTextSharp.text.pdf.PdfStream)PDFObj;
iTextSharp.text.pdf.PdfObject subtype = PDFStremObj.Get(iTextSharp.text.pdf.PdfName.SUBTYPE);
if ((subtype != null) && subtype.ToString() == iTextSharp.text.pdf.PdfName.IMAGE.ToString())
{
try
{
iTextSharp.text.pdf.parser.PdfImageObject PdfImageObj =
new iTextSharp.text.pdf.parser.PdfImageObject((iTextSharp.text.pdf.PRStream)PDFStremObj);
System.Drawing.Image ImgPDF = PdfImageObj.GetDrawingImage();
ImgList.Add(ImgPDF);
}
catch (Exception)
{
}
}
}
}
PDFReaderObj.Close();
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
return ImgList;
}
So am i doing something wrong? or is any way to know what page is processing to associate a image with a pdf page?
I am compressing a pdf containing a number of images. The below code I got while browsing for the PDF compression. It works fine for RBG format images but in case of CMYK format the images appears with inverted colours (as a negative). Somehow I was able to convert the inverted colours but the image colour got faded.
Please suggest how should I proceed. Thanks in advance.
{
PdfReader.unethicalreading = true;
string pdfFile = #"C:\TestPdf.pdf";
PdfReader reader = new PdfReader(pdfFile);
long quality = 50L;
int n = reader.XrefSize;
for (int i = 0; i < n; i++)
{
PdfObject obj = reader.GetPdfObject(i);
if (obj == null || !obj.IsStream()) { continue; }
PdfDictionary dict = (PdfDictionary)PdfReader.GetPdfObject(obj);
PdfObject pdfcolorspace = dict.Get(PdfName.COLORSPACE);
PdfName subType = (PdfName)PdfReader.GetPdfObject(dict.Get(PdfName.SUBTYPE));
if (!PdfName.IMAGE.Equals(subType)) { continue; }
PRStream stream = (PRStream)obj;
try
{
PdfImageObject image = new PdfImageObject(stream);
PdfName filter = (PdfName)image.Get(PdfName.FILTER);
if ( PdfName.JBIG2DECODE.Equals(filter) || PdfName.JPXDECODE.Equals(filter) || PdfName.CCITTFAXDECODE.Equals(filter) || PdfName.FLATEDECODE.Equals(filter))
continue;
System.Drawing.Image img = image.GetDrawingImage();
if (img == null) continue;
var ll = image.GetImageBytesType();
int width = img.Width;
int height = img.Height;
using (System.Drawing.Bitmap dotnetImg = new System.Drawing.Bitmap(img))
{
System.Drawing.Imaging.ImageCodecInfo codec = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders()[1];
System.Drawing.Imaging.EncoderParameters eParams = new System.Drawing.Imaging.EncoderParameters(1);
eParams.Param[0] = new System.Drawing.Imaging.EncoderParameter( System.Drawing.Imaging.Encoder.Quality, quality);
using (MemoryStream msImg = new MemoryStream())
{
dotnetImg.Save(msImg, codec, eParams);
msImg.Position = 0;
stream.Clear();
if (pdfcolorspace == PdfName.DEVICECMYK)
{
img.Save(msImg, ImageFormat.Jpeg);
stream.Put(PdfName.COLORSPACE, PdfName.DEVICECMYK);
}
else
{
stream.Put(PdfName.COLORSPACE, PdfName.DEVICERGB);
}
stream.SetData( msImg.ToArray(), true, PdfStream.BEST_COMPRESSION);
stream.Put(PdfName.TYPE, PdfName.XOBJECT);
stream.Put(PdfName.SUBTYPE, PdfName.IMAGE);
stream.Put(PdfName.FILTER, PdfName.DCTDECODE);
stream.Put(PdfName.WIDTH, new PdfNumber(width));
stream.Put(PdfName.HEIGHT, new PdfNumber(height));
stream.Put(PdfName.BITSPERCOMPONENT, new PdfNumber(8));
}
}
}
catch (Exception ex)
{
}
finally
{
reader.RemoveUnusedObjects();
}
}
PdfStamper stamper = new PdfStamper(reader, new FileStream(#"C:\Compress.pdf", FileMode.Create), PdfWriter.VERSION_1_5);
stamper.FormFlattening = false;
stamper.SetFullCompression();
stamper.Close();
reader.Close();
}