Рисунок маски Gdiplus из другого изображения

Как сказал Барри, люди воспользовались преимуществами; Один из способов, которым это было использовано, был для отслеживания единичных случаев. Если вы посмотрите на классическую реализацию синглтона, вы увидите это:

  // Example implementation of the Singleton pattern.
  TSingleton = class(TObject)
  protected
    constructor CreateInstance; virtual;
    class function AccessInstance(Request: Integer): TSingleton;
  public
    constructor Create; virtual;
    destructor Destroy; override;
    class function Instance: TSingleton;
    class procedure ReleaseInstance;
  end;

constructor TSingleton.Create;
begin
  inherited Create;

  raise Exception.CreateFmt('Access class %s through Instance only', [ClassName]);
end;

constructor TSingleton.CreateInstance;
begin
  inherited Create;

  // Do whatever you would normally place in Create, here.
end;

destructor TSingleton.Destroy;
begin
  // Do normal destruction here

  if AccessInstance(0) = Self then
    AccessInstance(2);

  inherited Destroy;
end;

{$WRITEABLECONST ON}
class function TSingleton.AccessInstance(Request: Integer): TSingleton;
const
  FInstance: TSingleton = nil;
begin
  case Request of
    0 : ;
    1 : if not Assigned(FInstance) then
          FInstance := CreateInstance;
    2 : FInstance := nil;
  else
    raise Exception.CreateFmt('Illegal request %d in AccessInstance', [Request]);
  end;
  Result := FInstance;
end;
{$IFNDEF WRITEABLECONST_ON}
  {$WRITEABLECONST OFF}
{$ENDIF}

class function TSingleton.Instance: TSingleton;
begin
  Result := AccessInstance(1);
end;

class procedure TSingleton.ReleaseInstance;
begin
  AccessInstance(0).Free;
end;
1
задан Anurag Uniyal 1 July 2009 в 12:49
поделиться

1 ответ

Я думаю, вы правы в том, что вам нужно делать это попиксельно. Я также искал более "чистый" способ сделать это, но в итоге я получил следующее:

    public enum ChannelARGB
    {
        Blue = 0,
        Green = 1,
        Red = 2,
        Alpha = 3
    }

    public static void transferOneARGBChannelFromOneBitmapToAnother(
        Bitmap source,
        Bitmap dest,
        ChannelARGB sourceChannel,
        ChannelARGB destChannel )
    {
        if ( source.Size!=dest.Size )
            throw new ArgumentException();
        Rectangle r = new Rectangle( Point.Empty, source.Size );
        BitmapData bdSrc = source.LockBits( r, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb );
        BitmapData bdDst = dest.LockBits( r, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb );
        unsafe
        {
            byte* bpSrc = (byte*)bdSrc.Scan0.ToPointer();
            byte* bpDst = (byte*)bdDst.Scan0.ToPointer();
            bpSrc += (int)sourceChannel;
            bpDst += (int)destChannel;
            for ( int i = r.Height * r.Width; i > 0; i-- )
            {
                *bpDst = *bpSrc;
                bpSrc += 4;
                bpDst += 4;
            }
        }
        source.UnlockBits( bdSrc );
        dest.UnlockBits( bdDst );
    }
2
ответ дан 3 September 2019 в 01:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: