简体   繁体   中英

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM