概述
我正在使用WinForms
。在我的代码中,我有这种方法。我正在尝试使用此代码按比例重新调整tif
图片的大小。我的目标是从流(源)获取图像并重新调整大小。我想重新调整大小的图像是tif
有多个页面的文档。我怎样才能按比例重新调整图像的大小?如何在图像盒打开之前调整图像大小
代码功能&计划
下面的代码是在另一个线程缓存tif
图像。问题是我的图像真的很大tif
。当我用多个页面打开这些真正大的tif
图像时,我的应用程序崩溃并滞后。我的目标或想法是在图像加载之前,我应该重新调整它的大小,以便应用程序不会崩溃并且性能变得更快。
例的Tif文件:
我创作了大量的tif文件测试你可以从这个链接下载:http://www.filedropper.com/tiftestingdoc
class PageBuffer : IDisposable
{
public const int DefaultCacheSize = 5;
public static PageBuffer Open(string path, int cacheSize = DefaultCacheSize)
{
return new PageBuffer(File.OpenRead(path), cacheSize);
}
private PageBuffer(Stream stream, int cacheSize)
{
this.stream = stream;
source = Image.FromStream(stream);
pageCount = source.GetFrameCount(FrameDimension.Page);
if (pageCount < 2) return;
pageCache = new Image[Math.Min(pageCount, Math.Max(cacheSize, 3))];
var worker = new Thread(LoadPages) { IsBackground = true };
worker.Start();
}
private void LoadPages()
{
while (true)
{
lock (syncLock)
{
if (disposed) return;
int index = Array.FindIndex(pageCache, 0, pageCacheSize, p => p == null);
if (index < 0)
Monitor.Wait(syncLock);
else
pageCache[index] = LoadPage(pageCacheStart + index);
}
}
}
private Image LoadPage(int index)
{
source.SelectActiveFrame(FrameDimension.Page, index);
return new Bitmap(source);
}
private Stream stream;
private Image source;
private int pageCount;
private Image[] pageCache;
private int pageCacheStart, pageCacheSize;
private object syncLock = new object();
private bool disposed;
public Image Source { get { return source; } }
public int PageCount { get { return pageCount; } }
public Image GetPage(int index)
{
if (disposed) throw new ObjectDisposedException(GetType().Name);
if (PageCount < 2) return Source;
lock (syncLock)
{
AdjustPageCache(index);
int cacheIndex = index - pageCacheStart;
var image = pageCache[cacheIndex];
if (image == null)
image = pageCache[cacheIndex] = LoadPage(index);
return image;
}
}
private void AdjustPageCache(int pageIndex)
{
int start, end;
if ((start = pageIndex - pageCache.Length/2) <= 0)
end = (start = 0) + pageCache.Length;
else if ((end = start + pageCache.Length) >= PageCount)
start = (end = PageCount) - pageCache.Length;
if (start < pageCacheStart)
{
int shift = pageCacheStart - start;
if (shift >= pageCacheSize)
ClearPageCache(0, pageCacheSize);
else
{
ClearPageCache(pageCacheSize - shift, pageCacheSize);
for (int j = pageCacheSize - 1, i = j - shift; i >= 0; j--, i--)
Exchange(ref pageCache[i], ref pageCache[j]);
}
}
else if (start > pageCacheStart)
{
int shift = start - pageCacheStart;
if (shift >= pageCacheSize)
ClearPageCache(0, pageCacheSize);
else
{
ClearPageCache(0, shift);
for (int j = 0, i = shift; i < pageCacheSize; j++, i++)
Exchange(ref pageCache[i], ref pageCache[j]);
}
}
if (pageCacheStart != start || pageCacheStart + pageCacheSize != end)
{
pageCacheStart = start;
pageCacheSize = end - start;
Monitor.Pulse(syncLock);
}
}
void ClearPageCache(int start, int end)
{
for (int i = start; i < end; i++)
Dispose(ref pageCache[i]);
}
static void Dispose<T>(ref T target) where T : class, IDisposable
{
var value = target;
if (value != null) value.Dispose();
target = null;
}
static void Exchange<T>(ref T a, ref T b) { var c = a; a = b; b = c; }
public void Dispose()
{
if (disposed) return;
lock (syncLock)
{
disposed = true;
if (pageCache != null)
{
ClearPageCache(0, pageCacheSize);
pageCache = null;
}
Dispose(ref source);
Dispose(ref stream);
if (pageCount > 2)
Monitor.Pulse(syncLock);
}
}
}
什么没有按没有与你尝试过的东西一起工作? – Jacobr365
我试过的方法之一就是这样,但图像质量下降,应用程序仍然有点慢。如果我重新调整大小,唯一的方法就是不要打破它。那么这是我想出来的解决方案,(源,800,1100),当我这样做,它工作正常。如果我不这样做,应用程序停止并给我一个错误OutOfMemoryException未处理我的进程内存是864。@ Jacobr365 – taji01