OSDN Git Service

MemoryImage.CopyFromBitmapの引数をImage型に変更
[opentween/open-tween.git] / OpenTween / MediaItem.cs
1 // OpenTween - Client of Twitter
2 // Copyright (c) 2015 spx (@5px)
3 // All rights reserved.
4 // 
5 // This file is part of OpenTween.
6 // 
7 // This program is free software; you can redistribute it and/or modify it
8 // under the terms of the GNU General Public License as published by the Free
9 // Software Foundation; either version 3 of the License, or (at your option)
10 // any later version.
11 // 
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 // for more details. 
16 // 
17 // You should have received a copy of the GNU General Public License along
18 // with this program. If not, see <http://www.gnu.org/licenses/>, or write to
19 // the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
20 // Boston, MA 02110-1301, USA.
21
22 using System;
23 using System.Drawing;
24 using System.IO;
25 using System.Linq;
26 using System.Threading;
27
28 namespace OpenTween
29 {
30     public interface IMediaItem
31     {
32         /// <summary>
33         /// メディアへの絶対パス
34         /// </summary>
35         string Path { get; }
36
37         /// <summary>
38         /// メディア名
39         /// </summary>
40         string Name { get; }
41
42         /// <summary>
43         /// メディアの拡張子
44         /// </summary>
45         string Extension { get; }
46
47         /// <summary>
48         /// メディアが存在するかどうかを示す真偽値
49         /// </summary>
50         bool Exists { get; }
51
52         /// <summary>
53         /// メディアのサイズ(バイト単位)
54         /// </summary>
55         long Size { get; }
56
57         /// <summary>
58         /// 表示用の MemoryImage を作成する
59         /// </summary>
60         /// <remarks>
61         /// 呼び出し側にて破棄すること
62         /// </remarks>
63         MemoryImage CreateImage();
64
65         /// <summary>
66         /// メディアの内容を読み込むための Stream を開く
67         /// </summary>
68         /// <remarks>
69         /// 呼び出し側にて閉じること
70         /// </remarks>
71         Stream OpenRead();
72
73         /// <summary>
74         /// メディアの内容を Stream へ書き込む
75         /// </summary>
76         void CopyTo(Stream stream);
77     }
78
79     /// <summary>
80     /// ファイル用の MediaItem クラス
81     /// </summary>
82     public class FileMediaItem : IMediaItem
83     {
84         private readonly FileInfo _fileInfo;
85
86         public FileMediaItem(string path)
87         {
88             this._fileInfo = new FileInfo(path);
89         }
90
91         public FileMediaItem(FileInfo fileInfo)
92             : this(fileInfo.FullName)
93         {
94         }
95
96         public string Path
97         {
98             get { return this._fileInfo.FullName; }
99         }
100
101         public string Name
102         {
103             get { return this._fileInfo.Name; }
104         }
105
106         public string Extension
107         {
108             get { return this._fileInfo.Extension; }
109         }
110
111         public bool Exists
112         {
113             get { return this._fileInfo.Exists; }
114         }
115
116         public long Size
117         {
118             get { return this._fileInfo.Length; }
119         }
120
121         public MemoryImage CreateImage()
122         {
123             using (var fs = this._fileInfo.OpenRead())
124             {
125                 return MemoryImage.CopyFromStream(fs);
126             }
127         }
128
129         public Stream OpenRead()
130         {
131             return this._fileInfo.OpenRead();
132         }
133
134         public void CopyTo(Stream stream)
135         {
136             using (var fs = this._fileInfo.OpenRead())
137             {
138                 fs.CopyTo(stream);
139             }
140         }
141
142         public FileInfo FileInfo
143         {
144             get { return this._fileInfo; }
145         }
146     }
147
148     /// <summary>
149     /// MemoryImage 用の MediaItem クラス
150     /// </summary>
151     /// <remarks>
152     /// 用途の関係上、メモリ使用量が大きくなるため、不要になればできるだけ破棄すること
153     /// </remarks>
154     public class MemoryImageMediaItem : IMediaItem, IDisposable
155     {
156         public const string PathPrefix = "<>MemoryImage://";
157         private static int _fileNumber = 0;
158
159         private bool _disposed = false;
160
161         private readonly string _path;
162         private readonly MemoryImage _image;
163
164         public MemoryImageMediaItem(Image image)
165         {
166             if (image == null)
167                 throw new ArgumentNullException("image");
168
169             // image から png 形式の MemoryImage を生成
170             this._image = MemoryImage.CopyFromImage(image);
171
172             var num = Interlocked.Increment(ref _fileNumber);
173             this._path = PathPrefix + num + this._image.ImageFormatExt;
174         }
175
176         public string Path
177         {
178             get { return this._path; }
179         }
180
181         public string Name
182         {
183             get { return this._path.Substring(PathPrefix.Length); }
184         }
185
186         public string Extension
187         {
188             get { return this._image.ImageFormatExt; }
189         }
190
191         public bool Exists
192         {
193             get { return this._image != null; }
194         }
195
196         public long Size
197         {
198             get { return this._image.Stream.Length; }
199         }
200
201         public MemoryImage CreateImage()
202         {
203             return this._image.Clone();
204         }
205
206         public Stream OpenRead()
207         {
208             // コピーを作成する
209             var memstream = new MemoryStream();
210
211             this._image.Stream.WriteTo(memstream);
212             memstream.Seek(0, SeekOrigin.Begin);
213
214             return memstream;
215         }
216
217         public void CopyTo(Stream stream)
218         {
219             this._image.Stream.WriteTo(stream);
220         }
221
222         protected virtual void Dispose(bool disposing)
223         {
224             if (this._disposed) return;
225
226             if (disposing)
227             {
228                 this._image.Dispose();
229             }
230
231             this._disposed = true;
232         }
233
234         public void Dispose()
235         {
236             this.Dispose(true);
237
238             // 明示的にDisposeが呼ばれた場合はファイナライザを使用しない
239             GC.SuppressFinalize(this);
240         }
241
242         ~MemoryImageMediaItem()
243         {
244             this.Dispose(false);
245         }
246     }
247 }