how to get header text with image from .DOCX file - c#

i want to get header image form doc file. i use following code it gives me image path but i can't get it
DocumentFormat.OpenXml.Packaging.ImagePart img = header.ImageParts.FirstOrDefault();
string imgpath = img.Uri.OriginalString;

I think your approach didn't work because the doc file is a zip file.
I don't know in which format you need that image, but you can try something like this to retrieve an image object. I updated my answer with an working example hope it helps.
using (var document = WordprocessingDocument.Open("your document path", true))
{
//Get the header
var header = document.MainDocumentPart.HeaderParts.First();
//These are your paragraphs where you can get the headers Text from
var paragraphList = header.Header.Descendants<DocumentFormat.OpenXml.Wordprocessing.Paragraph>();
//Get the imageId
string imgId = header.GetIdOfPart(header.ImageParts.First());
var imageSource=new BitmapImage();
//Get the imageStream
using (var imgStream = ((ImagePart)header.GetPartById(imgId)).GetStream())
{
//Copy stream to BitmapImage
using (var memoryStream = new MemoryStream())
{
imgStream.CopyTo(memoryStream);
memoryStream.Position = 0;
imageSource.BeginInit();
imageSource.CreateOptions = BitmapCreateOptions.PreservePixelFormat;
imageSource.CacheOption = BitmapCacheOption.OnLoad;
imageSource.UriSource = null;
imageSource.StreamSource = memoryStream;
imageSource.EndInit();
}
imageSource.Freeze();
//Save BitmapImage to file
var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(imageSource));
using (var stream = new FileStream("your path for the image.png", FileMode.Create))
encoder.Save(stream);
}
}
and this is an example how you can get position of your picture, but keep in mind it will only work if your picture got an absolute position.
List<DocumentFormat.OpenXml.Wordprocessing.Drawing> sdtElementDrawing =
header.Header.Descendants<DocumentFormat.OpenXml.Wordprocessing.Drawing>().ToList();
var distL= sdtElementDrawing.First().Anchor.DistanceFromLeft;

Related

Add image to a word page using memory stream

I am trying to use the memory stream to add an image to a word document. If I get the page from a file everithing works correctly(the commented code). How can I add the same image from the Byte array. I added AddImageToCell( I borrowed the method from the net).
C# WordprocessingDocument - insert an image in a cell
//string imageFile = #"C:\Users\Laptop\Desktop\test.png";
//ImagePart imagePart = document.MainDocumentPart.AddImagePart(ImagePartType.Jpeg);
//using (FileStream stream = new FileStream(imageFile, FileMode.Open))
//{
// imagePart.FeedData(stream);
//}
//AddImageToCell(tc3, document.MainDocumentPart.GetIdOfPart(imagePart));
byte[] signatureTempl = File.ReadAllBytes(#"C:\Users\Laptop\Desktop\test.png");
ImagePart imagePart = document.MainDocumentPart.AddImagePart(ImagePartType.Jpeg);
using (MemoryStream ms = new MemoryStream())
{
using (Bitmap bitmap = new Bitmap())
{
bitmap.Save(ms, ImageFormat.Jpeg);
ms.Position = 0;
imagePart.FeedData(ms);
}
AddImageToCell(tc3, document.MainDocumentPart.GetIdOfPart(imagePart));
}

Changing image size from stream

I've searched here for help with this, but nothing quite matches what I need. I have an image that gets uploaded, and I'd like to change the size before it gets saved to azure.
So currently my code is:
public ActionResult UserDetails(HttpPostedFileBase photo)
{ var inputFile = new Photo()
{
FileName = photo.FileName,
Data = () => photo.InputStream
};
//then I save to Azure
How would I change the photo.InputStream to 100x 100 px for example?
Here is how I do it:
byte[] imageBytes;
//Of course image bytes is set to the bytearray of your image
using (MemoryStream ms = new MemoryStream(imageBytes, 0, imageBytes.Length))
{
using (Image img = Image.FromStream(ms))
{
int h = 100;
int w = 100;
using (Bitmap b = new Bitmap(img, new Size(w,h)))
{
using (MemoryStream ms2 = new MemoryStream())
{
b.Save(ms2, System.Drawing.Imaging.ImageFormat.Jpeg);
imageBytes = ms2.ToArray();
}
}
}
}
From there, I use a MemoryStream to upload. I use blob storage and use the UploadFromStreamAsync to load to blob.
This is a basic view of it.

ObjectDisposedException when I try to use an Image source

I need to add an Image to my Panel, so I use the following code:
var image = new Image();
var source = new BitmapImage();
source.BeginInit();
source.CacheOption = BitmapCacheOption.OnLoad;
source.StreamSource = new FileStream(filename, FileMode.Open);
source.EndInit();
// I close the StreamSource so I can load again the same file
source.StreamSource.Close();
image.Source = source;
The problem is that when I try to use my image source I get an ObjectDisposedException:
var source = ((BitmapImage)image.Source).StreamSource;
// When I use source I get the exception
using (var stream = new MemoryStream((int)(source.Length)))
{
source.Position = 0;
source.CopyTo(stream);
// ...
}
It happens because I closed the source, but if I don't close it I can't be able to load again the same file.
How can I solve this problem (i.e. close the source to be able to load the same file more than once, and to be able to use the source without get the exception)?
The following solution should work for you:
var image = new Image();
var source = new BitmapImage();
source.BeginInit();
source.CacheOption = BitmapCacheOption.OnLoad;
// Create a new stream without disposing it!
source.StreamSource = new MemoryStream();
using (var filestream = new FileStream(filename, FileMode.Open))
{
// Copy the file stream and set the position to 0
// or you will get a FileFormatException
filestream.CopyTo(source.StreamSource);
source.StreamSource.Position = 0;
}
source.EndInit();
image.Source = source;

Upload image to a server from PictureBox

I have one pictureBox and a button on form1 one. When the button is clicked, it should upload the file to the server. For now I am using the below method. First save the image locally and then upload to the server:
Bitmap bmp = new Bitmap(this.form1.pictureBox1.Width, this.form1.pictureBox1.Height);
Graphics g = Graphics.FromImage(bmp);
Rectangle rect = this.form1.pictureBox1.RectangleToScreen(this.form1.pictureBox1.ClientRectangle);
g.CopyFromScreen(rect.Location, Point.Empty, this.form1.pictureBox1.Size);
g.Dispose();
bmp.Save("filename", ImageFormat.Jpeg);
And then uploading that file:
using (var f = System.IO.File.OpenRead(#"F:\filename.jpg"))
{
HttpClient client = new HttpClient();
var content = new StreamContent(f);
var mpcontent = new MultipartFormDataContent();
content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
mpcontent.Add(content);
client.PostAsync("http://domain.com/upload.php", mpcontent);
}
I can't use the Bitmap type in StreamContent. How can I stream the image from pictureBox directly instead saving it as file first?
I came up with the below code using MemoryStream, but the uploaded file size is 0 using this method. Why?
byte[] data;
using (MemoryStream m = new MemoryStream())
{
bmp.Save(m, ImageFormat.Png);
m.ToArray();
data = new byte[m.Length];
m.Write(data, 0, data.Length);
HttpClient client = new HttpClient();
var content = new StreamContent(m);
var mpcontent = new MultipartFormDataContent();
content.Headers.ContentType = new MediaTypeHeaderValue("image/png");
mpcontent.Add(content, "file", filename + ".png");
HttpResponseMessage response = await client.PostAsync("http://domain.com/upload.php", mpcontent);
//response.EnsureSuccessStatusCode();
string body = await response.Content.ReadAsStringAsync();
MessageBox.Show(body);
}
I am not sure if it is the correct way to do it, but I have solved it by creating a new stream and then copying the older one to it:
using (MemoryStream m = new MemoryStream())
{
m.Position = 0;
bmp.Save(m, ImageFormat.Png);
bmp.Dispose();
data = m.ToArray();
MemoryStream ms = new MemoryStream(data);
// Upload ms
}
Image returnImage = Image.FromStream(....);

Multi page tiff program Blank pages

I write a code to combine single tiff file to multipage tiff. but output come with the blank pages at the end. code works fine if the input files are black&White but not for colored .tiff files. for example if i give 100 files and as input output single tiff files come up with 47 pages and rest of them are blank.
i use standard code to achieve this functionality, following is my code. Anyone idea why ?
using (FileStream fs = new FileStream(fileNameTemp, FileMode.Append, FileAccess.Write))
{
System.Windows.Media.Imaging.TiffBitmapEncoder tifEnc = new System.Windows.Media.Imaging.TiffBitmapEncoder();
tifEnc.Compression = System.Windows.Media.Imaging.TiffCompressOption.Default;
foreach (string fileName1 in filePaths)
{
Console.WriteLine("FileName:::" + fileName1);
System.Windows.Media.Imaging.BitmapImage bmpImg = new System.Windows.Media.Imaging.BitmapImage();
bmpImg.BeginInit();
bmpImg.CacheOption = System.Windows.Media.Imaging.BitmapCacheOption.OnLoad;
bmpImg.UriSource = new Uri(fileName1);
bmpImg.EndInit();
System.Windows.Media.Imaging.FormatConvertedBitmap fcb = new System.Windows.Media.Imaging.FormatConvertedBitmap(bmpImg,
System.Windows.Media.PixelFormats.Rgb24,
System.Windows.Media.Imaging.BitmapPalettes.Halftone27,
1.0);
tifEnc.Frames.Add(System.Windows.Media.Imaging.BitmapFrame.Create(fcb));
}
tifEnc.Save(fs);
fs.Dispose();
}
Thanks in advance!
In the sample below, BitmapImage is not loaded when you do bitmapImage.EndInit() as it seems to be doing lazy loading. If the memory stream is disposed, then the pages I get are also white because the image is not loaded.
The second method takes a destination file path and a list of sources.
public static BitmapImage LoadImage(byte[] bytes)
{
var memoryStream = new MemoryStream(bytes);
var bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.StreamSource = memoryStream;
bitmapImage.EndInit();
return bitmapImage;
}
public static void CreateTiff(string destPath, params string[] filePaths)
{
using (FileStream fs = new FileStream(destPath, FileMode.Append,
FileAccess.Write))
{
var tifEnc = new TiffBitmapEncoder();
tifEnc.Compression = TiffCompressOption.Default;
foreach (string fileName in filePaths)
{
var image = LoadImage(File.ReadAllBytes(fileName));
tifEnc.Frames.Add(BitmapFrame.Create(image));
}
tifEnc.Save(fs);
}
}

Categories

Resources