Multi page tiff program Blank pages - c#

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);
}
}

Related

how to get header text with image from .DOCX file

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;

wp8 Operation not permitted on IsolatedStorageFileStream

I am copying all images from my device to directory. While copying the images I am getting this error Operation not permitted on IsolatedStorageFileStream.
Here is my code to copy the files.
MediaLibrary m = new MediaLibrary();
using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication())
{
if (store.DirectoryExists("ImagesZipFolder"))
{
deleteFileFolder("ImagesZipFolder");
}
if (!store.DirectoryExists("ImagesZipFolder"))
{
store.CreateDirectory("ImagesZipFolder");
foreach (var picture in m.Pictures)
{
using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(#"ImagesZipFolder/" + picture.Name, FileMode.CreateNew, store))
{
BitmapImage image = new BitmapImage();
image.SetSource(picture.GetImage());
byte[] bytes = ConvertToBytes(image);
stream.Write(bytes, 0, bytes.Length);
}
}
}
}
Here is my ConvertToBytes method.
public byte[] ConvertToBytes(BitmapImage bitmapImage)
{
byte[] data = null;
WriteableBitmap wBitmap = null;
using (MemoryStream stream = new MemoryStream())
{
wBitmap = new WriteableBitmap(bitmapImage);
wBitmap.SaveJpeg(stream, wBitmap.PixelWidth, wBitmap.PixelHeight, 0, 100);
stream.Seek(0, SeekOrigin.Begin);
//data = stream.GetBuffer();
data = stream.ToArray();
DisposeImage(bitmapImage);
return data;
}
}
Basically what I am trying is to create a zip file of all images. I have total 222 images in my device. So how can I solve this issue ? How can I create a zip of this images?
Most probably this is due to the concurrent access to the file
you can refer to the link:
Operation not permitted on IsolatedStorageFileStream. error
I checked your code and it seems to be working (providing there's no error in DisposeImage() method) There is no OperationNotPermittedException occuring. However, if there is error in your code, then it can only be because of deleteFileFolder("ImagesZipFolder") line. Can you give me the snippet so that I can study it further. I m posting the working code... I have replaced that method with simple predefined one--
MediaLibrary m = new MediaLibrary();
using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication())
{
if (store.DirectoryExists("ImagesZipFolder"))
{
store.DeleteDirectory("ImagesZipFolder");
}
if (!store.DirectoryExists("ImagesZipFolder"))
{
store.CreateDirectory("ImagesZipFolder");
foreach (var picture in m.Pictures)
{
using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(#"ImagesZipFolder/" + picture.Name, FileMode.CreateNew, store))
{
BitmapImage image = new BitmapImage();
image.SetSource(picture.GetImage());
byte[] bytes = ConvertToBytes(image);
stream.Write(bytes, 0, bytes.Length);
}
}
}
}

How to save image using JpegBitmapEncoder

According to the image encoding example here I should be able to use JpegBitmapEncoder to encode an image for saving as a jpeg file but get this compile error:
error CS1503: Argument 1: cannot convert from 'System.Windows.Controls.Image' to 'System.Uri'
I don't see a way (property or method in Image) to get System.Uri from Image.
What am I missing?
The Image xaml code is
<Image Name="ColorImage"/>
The SaveImage C# is
...
SaveImage(ColorImage, path);
...
private void SaveImage(Image image, string path)
{
var jpegEncoder = new JpegBitmapEncoder();
jpegEncoder.Frames.Add(BitmapFrame.Create(image));
using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write))
{
jpegEncoder.Save(fs);
}
}
The code below (taken mostly from the kinect-sdk) streams 640 x 480 RBG to a WriteableBitmap at 30 Fps (the kinect ColorImageFormat is RgbResolution640x480Fps30).
using (var colorImageFrame = allFramesReadyEventArgs.OpenColorImageFrame())
{
if (colorImageFrame == null) return;
var haveNewFormat = currentColorImageFormat != colorImageFrame.Format;
if (haveNewFormat)
{
currentColorImageFormat = colorImageFrame.Format;
colorImageData = new byte[colorImageFrame.PixelDataLength];
colorImageWritableBitmap = new WriteableBitmap(
colorImageFrame.Width,
colorImageFrame.Height, 96, 96, PixelFormats.Bgr32, null);
ColorImage.Source = colorImageWritableBitmap;
}
// Make a copy of the color frame for displaying.
colorImageFrame.CopyPixelDataTo(colorImageData);
colorImageWritableBitmap.WritePixels(
new Int32Rect(0, 0, colorImageFrame.Width, colorImageFrame.Height),
colorImageData,
colorImageFrame.Width*Bgr32BytesPerPixel,
0);
}
private void SaveImage(string path)
{
var jpegEncoder = new JpegBitmapEncoder();
jpegEncoder.Frames.Add(BitmapFrame.Create(colorImageWritableBitmap));
using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write))
{
jpegEncoder.Save(fs);
}
}
The problem occurs, because you pass an Image to BitmapFrame.Create. Imageis more common in Windows Forms. A simple approach would be to create a MemoryStream first and the pass this:
private void SaveImage(Image image, string path)
{
MemoryStream ms = new MemoryStream();
image.Save(ms,System.Drawing.Imaging.ImageFormat.Jpeg);
var jpegEncoder = new JpegBitmapEncoder();
jpegEncoder.Frames.Add(BitmapFrame.Create(ms));
using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write))
{
jpegEncoder.Save(fs);
}
}
Addition (see conversation in comments):
you could try to use the CopyPixels method on the writeableBitmap object and copy the pixels to a byte array which you load to a MemoryStream and the write it to a Jpeg File withe the JpegBitmapEncoder. But it's just a guess.
This could work, too:
private void SaveImage (WriteableBitmap img, string path)
{
FileStream stream = new FileStream(path, FileMode.Create);
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(img));
encoder.Save(stream);
stream.Close();
}
You will just have to extract the WriteableBitmap from your Image control
Try: BitmapFrame.Create(image.Source)

How to read image dimensions at C# wpf - there is no dispose method for BitmapImage

With the way below i am able to read.
But there is no dispose method so i am not able to delete the file later.
So the below method is getting failed.
I could not come up with a proper solution.
Bitmap class is not recognized in C# 4.5 WPF application.
thank you
DirectoryInfo dInfo = new DirectoryInfo(#"C:\pokemon_files\images\");
FileInfo[] subFiles = dInfo.GetFiles();
BitmapImage myImg;
foreach (var vrImage in subFiles)
{
string srFilePath = vrImage.FullName;
System.Uri myUri = new Uri(srFilePath);
myImg = new BitmapImage(myUri);
if (myImg.Width < 50)
{
File.Delete(srFilePath);
continue;
}
}
I assume the error you get is caused by trying to delete the file which is currently in use
by the bitmap (I don't remember the exception name).
There is a solution to that, that is: making a byte stream.
byte[] imageData;
using(var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
using(var binaryReader = new BinaryReader(fileStream))
{
imageData = binaryReader.ReadBytes((int)fileStream.Length);
}
var bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.StreamSource = new MemoryStream(imageData);
bitmap.EndInit();
//Now you can check the width & height, the file stream should be closed so you can
//delete the file.
[EDIT]
If you don't want to read the bytes by BinaryReader, there's always this solution if you want to read all bytes from the file.

C# - The process cannot access the file because it is being used by another process

public static void CopyImage(Image picToSave, string name)
{
if (picToSave.Source != null)
{
BitmapImage src = (BitmapImage)picToSave.Source;
if (!Directory.Exists("Images"))
{
Directory.CreateDirectory("Images");
}
FileStream stream = new FileStream("Images/" + name + ".jpg", FileMode.Create);
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(src));
encoder.Save(stream);
stream.Close();
}
}
The problem occurs when i choose a file which already exists in the /Images directory, i guess it just cant overwrite, The exception is thrown at the "FileStream"" line (FileMode.Create I guess).
If i Choose a file which isn't in the /Images directory it works fine and copies the file to the Images Directory like it should..
Thank you :)
How did you load the image in the first place? If you didn't change the default value for CacheOption, the file is locked by the BitmapImage object. You need to specify BitmapCacheOption.OnLoad:
BitmapImage image = new BitmapImage();
image.BeginInit();
image.UriSource = imageUri;
image.CacheOption = BitmapCacheOption.OnLoad;
image.EndInit();
Assuming you created Bitmaps from all the images in the image folder this sounds like a known problem with the Bitmap class - it keeps a file lock on the file you created it from until you call dispose. Also see this thread: .NET app locks file.
Hans Passant offers the following workaround in this thread: Loading a file to a Bitmap but leaving the original file intact
public static Image LoadImageNoLock(string path) {
using (var ms = new MemoryStream(File.ReadAllBytes(path))) {
return Image.FromStream(ms);
}
}
Just thought I would post something that worked for me from #Thomas Levesque's comment.
FileStream stream = new FileStream(imageLocation, FileMode.Open);
Image image = new Image();
BitmapImage bi = new BitmapImage();
bi.BeginInit();
bi.StreamSource = stream;
bi.CacheOption = BitmapCacheOption.OnLoad;
bi.EndInit();
image.Source = bi;
image.Height = 15;
btn.Content = image;
stream.Close();
stream.Dispose();
try with some modifications in your code
set the write permission to your opened file
FileStream stream = new FileStream("Images/" + name + ".jpg", FileMode.Create, FileAccess.Write);

Categories

Resources