将图像转换为流以进行即时处理
Converting images into Streams for on the fly processing
所以我使用 SharpZipLib 递归浏览我的文档并打包它找到的任何 JPEG 图像,如下所示:
foreach (string filename in filenames)
{
string[] file_split = filename.Split('.');
if (file_split[file_split.Count() - 1].Equals("jpg"))
{
// You might replace these 3 lines with your own stream code
ScaleImage scaleImage = new ScaleImage();
FileStream file = new FileStream("path to file", FileMode.Open);
using (Stream inputStream = File.OpenRead(filename))
{
string tarName = filename.Substring(3); // strip off "C:\"
Image tmpImg = scaleImage.scale(tmpImg);
long fileSize = inputStream.Length;
// Create a tar entry named as appropriate. You can set the name to anything,
// but avoid names starting with drive or UNC
TarEntry entry = TarEntry.CreateTarEntry(tarName);
// Must set size, otherwise TarOutputStream will fail when output exceeds.
entry.Size = fileSize;
// Add the entry to the tar stream, before writing the data.
tarOutputStream.PutNextEntry(entry);
// this is copied from TarArchive.WriteEntryCore
byte[] localBuffer = new byte[32 * 1024];
while (true)
{
int numRead = inputStream.Read(localBuffer, 0, localBuffer.Length);
if (numRead <= 0)
{
break;
}
tarOutputStream.Write(localBuffer, 0, numRead);
}
}
tarOutputStream.CloseEntry();
}
}
// Recurse. Delete this if unwanted.
string[] directories = Directory.GetDirectories(sourceDirectory);
foreach (string directory in directories)
{
CreateTarManually(tarOutputStream, directory);
}
为了尽可能地减少 tar 大小 - 我试图在从流中读取图像时将所有图像调整为指定的宽度 x 高度 "on the fly"。我想我可以在它进入 using (Stream inputStream) 部分后从流中加载图像,并从那里使用找到的调整图像大小的函数。像这样:
public Bitmap scale(Image oldImage)
{
double resizeFactor = 1;
if (oldImage.Width > 150 || oldImage.Height > 150)
{
double widthFactor = Convert.ToDouble(oldImage.Width) / 150;
double heightFactor = Convert.ToDouble(oldImage.Height) / 150;
resizeFactor = Math.Max(widthFactor, heightFactor);
}
int width = Convert.ToInt32(oldImage.Width / resizeFactor);
int height = Convert.ToInt32(oldImage.Height / resizeFactor);
Bitmap newImage = new Bitmap(width, height);
Graphics g = Graphics.FromImage(newImage);
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.DrawImage(oldImage, 0, 0, newImage.Width, newImage.Height);
return newImage;
}
我的问题是,如何传递要调整大小的流对象,然后将流 object/resized 对象添加到 tar 文件,而不是原始文件本身?实际上,我希望所有这些都在内存中完成,以节省在调整磁盘大小时复制磁盘上的每个文件
将使用 here 的答案。
public Stream ImageToStream(Image image)
{
//Save to stream
MemoryStream stream = new MemoryStream();
image.Save(stream, ImageFormat.Jpeg);
stream.Seek(0, SeekOrigin.Begin); //Need to reset position to 0
return stream;
}
并且不使用文件中的输入流,而是使用函数中的输入流:
Image oldImage = Image.FromFile(fileName);
Image newImage = scale(oldImage);
Stream inputStream = ImageToStream(newImage);
奖金建议:
如果要检查文件扩展名,可以这样使用Path.GetExtension(fileName)
:
var fileExtension = Path.GetExtension(filename);
if (fileExtension.Equals(".jpg"))
{
//ApplyLogic
}
所以我使用 SharpZipLib 递归浏览我的文档并打包它找到的任何 JPEG 图像,如下所示:
foreach (string filename in filenames)
{
string[] file_split = filename.Split('.');
if (file_split[file_split.Count() - 1].Equals("jpg"))
{
// You might replace these 3 lines with your own stream code
ScaleImage scaleImage = new ScaleImage();
FileStream file = new FileStream("path to file", FileMode.Open);
using (Stream inputStream = File.OpenRead(filename))
{
string tarName = filename.Substring(3); // strip off "C:\"
Image tmpImg = scaleImage.scale(tmpImg);
long fileSize = inputStream.Length;
// Create a tar entry named as appropriate. You can set the name to anything,
// but avoid names starting with drive or UNC
TarEntry entry = TarEntry.CreateTarEntry(tarName);
// Must set size, otherwise TarOutputStream will fail when output exceeds.
entry.Size = fileSize;
// Add the entry to the tar stream, before writing the data.
tarOutputStream.PutNextEntry(entry);
// this is copied from TarArchive.WriteEntryCore
byte[] localBuffer = new byte[32 * 1024];
while (true)
{
int numRead = inputStream.Read(localBuffer, 0, localBuffer.Length);
if (numRead <= 0)
{
break;
}
tarOutputStream.Write(localBuffer, 0, numRead);
}
}
tarOutputStream.CloseEntry();
}
}
// Recurse. Delete this if unwanted.
string[] directories = Directory.GetDirectories(sourceDirectory);
foreach (string directory in directories)
{
CreateTarManually(tarOutputStream, directory);
}
为了尽可能地减少 tar 大小 - 我试图在从流中读取图像时将所有图像调整为指定的宽度 x 高度 "on the fly"。我想我可以在它进入 using (Stream inputStream) 部分后从流中加载图像,并从那里使用找到的调整图像大小的函数。像这样:
public Bitmap scale(Image oldImage)
{
double resizeFactor = 1;
if (oldImage.Width > 150 || oldImage.Height > 150)
{
double widthFactor = Convert.ToDouble(oldImage.Width) / 150;
double heightFactor = Convert.ToDouble(oldImage.Height) / 150;
resizeFactor = Math.Max(widthFactor, heightFactor);
}
int width = Convert.ToInt32(oldImage.Width / resizeFactor);
int height = Convert.ToInt32(oldImage.Height / resizeFactor);
Bitmap newImage = new Bitmap(width, height);
Graphics g = Graphics.FromImage(newImage);
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.DrawImage(oldImage, 0, 0, newImage.Width, newImage.Height);
return newImage;
}
我的问题是,如何传递要调整大小的流对象,然后将流 object/resized 对象添加到 tar 文件,而不是原始文件本身?实际上,我希望所有这些都在内存中完成,以节省在调整磁盘大小时复制磁盘上的每个文件
将使用 here 的答案。
public Stream ImageToStream(Image image)
{
//Save to stream
MemoryStream stream = new MemoryStream();
image.Save(stream, ImageFormat.Jpeg);
stream.Seek(0, SeekOrigin.Begin); //Need to reset position to 0
return stream;
}
并且不使用文件中的输入流,而是使用函数中的输入流:
Image oldImage = Image.FromFile(fileName);
Image newImage = scale(oldImage);
Stream inputStream = ImageToStream(newImage);
奖金建议:
如果要检查文件扩展名,可以这样使用Path.GetExtension(fileName)
:
var fileExtension = Path.GetExtension(filename);
if (fileExtension.Equals(".jpg"))
{
//ApplyLogic
}