object IExtractIcon.ExtractIcon(ExtractIconType type, Size desiredSize) { if (type == ExtractIconType.Thumbnail) { //// Have we already extracted the image? //if (cachedImage != null) // return cachedImage; // Do we support this extension? string ext = base.File.Extension.ToLowerInvariant(); if (ext == ".mif") { #if false using (Stream stream = base.File.OpenRead()) using (QQGame.MifImageDecoder mif = new QQGame.MifImageDecoder(stream)) { // TODO: should we dispose the original image??? Image img = mif.DecodeFrame().Image; return (Image)img.Clone(); } #else Stream stream = base.File.OpenRead(); QQGame.MifImage mif = new QQGame.MifImage(stream); mif.Name = base.File.Name; return mif; #endif } else if (ext == ".bmp" || ext == ".png") { using (Stream stream = base.File.OpenRead()) using (Bitmap bmp = new Bitmap(stream)) { // Make a copy of the bitmap, because MSDN says "You must // keep the stream open for the lifetime of the Bitmap." return bmp.Clone(); } } } return null; }
private void btnExport_Click(object sender, EventArgs e) { NewSaveImage(); return; #if false IVirtualItem vItem = vFolderListView.ActiveItem; if (vItem == null || !(vItem is IExtractIcon) || !(vItem is IVirtualFile)) { MessageBox.Show("No entry selected."); return; } IExtractIcon vIcon = vItem as IExtractIcon; object icon = vIcon.ExtractIcon(ExtractIconType.Thumbnail, Size.Empty); MultiFrameImage image; if (icon is MultiFrameImage) image = icon as MultiFrameImage; else if (icon is Image) image = new GdiImage(icon as Image); else { using (icon as IDisposable) { } return; } //ResourceListViewEntry ent = viewList.ActiveEntry; string ext = Path.GetExtension(vItem.Name).ToLowerInvariant(); string filter = "原始格式|*" + ext; // If the selected item is a multi-frame image, export as SVG. if (image.FrameCount > 1) { filter += "|SVG 动画|*.svg"; } // If the selected item is an image, display additional format // conversion options in the save dialog. if (true) { filter += "|PNG 图片|*.png"; filter += "|BMP 图片|*.bmp"; filter += "|JPEG 图片|*.jpg"; filter += "|TIFF 图片|*.tif"; } saveFileDialog1.Filter = filter; saveFileDialog1.FilterIndex = 1; if (image.FrameCount > 1) { saveFileDialog1.FilterIndex = 2; } saveFileDialog1.FileName = Path.GetFileNameWithoutExtension( vItem.Name); // Show the dialog. if (saveFileDialog1.ShowDialog(this) != DialogResult.OK) return; string filename = saveFileDialog1.FileName; // If the filter index is 1 (save as is), just copy the stream. if (saveFileDialog1.FilterIndex == 1) { using (Stream input = (vItem as IVirtualFile).Open()) using (Stream output = new FileStream(filename, FileMode.Create, FileAccess.Write)) { //This is .NET 2.0. //byte[] buffer = new byte[65536]; //int n; //while ((n = input.Read(buffer, 0, buffer.Length)) > 0) // output.Write(buffer, 0, n); try { input.CopyTo(output); } catch (Exception ex) { MessageBox.Show(this, "导出素材时遇到以下错误:\r\n" + ex.Message + "\r\n保存的文件可能不完整。", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error); } } txtStatus.Text = "保存成功"; image.Dispose(); return; } // Get the requested image format. int filterIndex = saveFileDialog1.FilterIndex; if (image.FrameCount > 1) filterIndex--; ImageFormat desiredFormat = (filterIndex == 2) ? ImageFormat.Png : (filterIndex == 3) ? ImageFormat.Bmp : (filterIndex == 4) ? ImageFormat.Jpeg : (filterIndex == 5) ? ImageFormat.Tiff : ImageFormat.Emf; // If this is a single-frame image, convert and save it. if (image.FrameCount <= 1) { image.Frame.Save(filename, desiredFormat); txtStatus.Text = "保存成功"; image.Dispose(); return; } // If this is a multi-frame image and user chooses to save as // SVG, do that. if (filterIndex == 1) { // TODO: fix this using (Stream input = (vItem as IVirtualFile).Open()) using (ImageDecoder decoder = new QQGame.MifImageDecoder(input)) using (Stream output = new FileStream(filename, FileMode.Create, FileAccess.Write)) using (ImageEncoder encoder = new SvgImageEncoder(output, decoder.FrameCount)) { for (int i = 0; i < decoder.FrameCount; i++) { Util.Media.ImageFrame frame = decoder.DecodeFrame(); using (frame.Image) { encoder.EncodeFrame(frame); } } } txtStatus.Text = "保存成功"; image.Dispose(); return; } // Now for a multi-frame image, ask the user how they want to save it. DialogResult result = MessageBox.Show(this, "选中的图片包含 " + image.FrameCount + " 帧。" + "是否将每一帧单独存为一个文件?\r\n" + "如果选择是,则各帧将分别保存为\r\n " + GetNumberedFileName(Path.GetFileName(filename), 1, image.FrameCount) + "\r\n" + " ......\r\n " + GetNumberedFileName(Path.GetFileName(filename), image.FrameCount, image.FrameCount) + "\r\n" + "如果选择否,则只保存第一帧到 " + Path.GetFileName(filename) + "。", this.Text, MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question); // Do nothing if the user is confused and canceled the action. if (result == DialogResult.Cancel) { image.Dispose(); return; } // If the user clicked "No", then we only save the first frame, // which is just the thumbnail. if (result == DialogResult.No) { image.Frame.Save(filename, desiredFormat); txtStatus.Text = "保存成功"; image.Dispose(); return; } // Now the user clicked "Yes", so we need to save each frame // in an individual file. for (int i = 0; i < image.FrameCount; i++) { image.FrameIndex = i; FileInfo file = new FileInfo( GetNumberedFileName(filename, i + 1, image.FrameCount)); if (file.Exists) { if (MessageBox.Show(this, "文件 " + file.FullName + " 已经存在。是否要覆盖?", "保存素材", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Exclamation) != DialogResult.Yes) { image.Dispose(); return; } } image.Frame.Save(file.FullName); } txtStatus.Text = "保存成功"; image.Dispose(); #endif }
/// <summary> /// Entry routine of the worker thread. /// </summary> private static void worker_DoWork(object sender, DoWorkEventArgs e) { Stack<ThumbnailTask> tasks = (e.Argument as Stack<ThumbnailTask>); while (true) { // Retrieve the next undone task in the task queue, starting // from the end because those are newer tasks. ThumbnailTask task = null; lock (tasks) { while (tasks.Count > 0) { task = tasks.Peek(); if (task.Tag.Thumbnail == null) break; tasks.Pop(); } if (tasks.Count == 0) // no more tasks return; } // Perform this task. ResourceListViewEntry tag = task.Tag; #if DEBUG && false System.Diagnostics.Debug.WriteLine("Starting task for item " + task.ItemIndex); #endif // Load the resource if its format is supported. if (tag.ResourceEntry is IVirtualFile) { IVirtualFile vFile = tag.ResourceEntry as IVirtualFile; string name = tag.ResourceEntry.Name.ToLowerInvariant(); try { if (name.EndsWith(".mif")) { using (Stream stream = vFile.Open(FileMode.Open, FileAccess.Read, FileShare.Read)) using (ImageDecoder mif = new QQGame.MifImageDecoder(stream)) { tag.Thumbnail = mif.DecodeFrame().Image; tag.FrameCount = mif.FrameCount; } } else if (name.EndsWith(".bmp")) { using (Stream stream = vFile.Open(FileMode.Open, FileAccess.Read, FileShare.Read)) { tag.Thumbnail = new Bitmap(stream); tag.FrameCount = 1; } } } catch (Exception ex) { System.Diagnostics.Debug.WriteLine( "Error loading " + name + ": " + ex.Message); } } // If a thumbnail image cannot be loaded, we use a default one. if (tag.Thumbnail == null) { tag.Thumbnail = DefaultIcon; tag.FrameCount = 1; } // Report progress. (sender as BackgroundWorker).ReportProgress(0, task); } }