开发者

Get raw data back from instance of Image

I'm getting Image (actually instance of Bitmap class) from resources, and (to write it to rtf stream) - I need it's raw data back.

Also, Image.Save method can't be used, because it seems to close stream it saving to, and I need to append to RTF file. I do not want to create new stream, save image to it, then copy 开发者_如何学编程it to RTF stream because of performance issues.


Create a filter stream that passes through to the stream you want to append to, but doesn't close that stream when it is itself closed:

public class AppendingStream : Stream
{
    private readonly long _startPos;
    private readonly Stream _sink;
    public AppendingStream(Stream sink)
    {
        if(sink == null)
            throw new ArgumentNullException();
        if(!sink.CanWrite)
            throw new ArgumentException();
        _sink = sink;
        try
        {
            _startPos = sink.Position;
        }
        catch(NotSupportedException)
        {
            _startPos = -1;
        }
    }
    public override bool CanRead
    {
        get
        {
            return false;
        }
    }
    public override bool CanSeek
    {
        get
        {
            return _sink.CanSeek && _startPos != -1;
        }
    }
    public override bool CanTimeout
    {
        get
        {
            return _sink.CanTimeout;
        }
    }
    public override bool CanWrite
    {
        get
        {
            return true;
        }
    }
    public override long Length
    {
        get
        {
            if(_startPos == -1)
                throw new NotSupportedException();
            return _sink.Length - _startPos;
        }
    }
    public override long Position
    {
        get
        {
            return _sink.Position - _startPos;
        }
        set
        {
            _sink.Position = value + _startPos;
        }
    }
    public override void Flush()
    {
        _sink.Flush();
    }
    public override int Read(byte[] buffer, int offset, int count)
    {
        throw new NotSupportedException();
    }
    public override int ReadByte()
    {
        throw new NotSupportedException();
    }
    public override long Seek(long offset, SeekOrigin origin)
    {
        if(origin == SeekOrigin.Begin)
            return _sink.Seek(offset + _startPos, SeekOrigin.Begin) - _startPos;
        else
            return _sink.Seek(offset, origin);
    }
    public override void SetLength(long value)
    {
        if(_startPos == -1)
            throw new NotSupportedException();
        _sink.SetLength(value + _startPos);
    }
    public override void Write(byte[] buffer, int offset, int count)
    {
        _sink.Write(buffer, offset, count);
    }
    public override void WriteByte(byte value)
    {
        _sink.WriteByte(value);
    }
}

Then you've no longer got the issue of the stream being closed, as it doesn't matter.

The bits to deal with seeking to new positions is because some image formats are written in a non-sequential manner. It won't work if the underlying stream doesn't support it, but then that wouldn't work anyway.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜