首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >颜色到ARGB转换

颜色到ARGB转换
EN

Stack Overflow用户
提问于 2015-02-13 10:11:51
回答 1查看 3K关注 0票数 0

我有一个整数色值,如-16447153.如何把它转换成ARGB?

在c#中,他使用了颜色函数,

代码语言:javascript
复制
Color.FromArgb(buf[buf_pos])

在delphi中是否有像上面这样的函数,否则我如何转换?

我试过这样做:

代码语言:javascript
复制
procedure TJP2RenderPreview.put_region(size : _Ckdu_coords; buf : array of Integer; offX, offY : Integer);
var
  x, y          : Integer;
  width, height : Integer;
  buf_pos       : Integer;
  RowPtr        : PRGBQuad;
begin
  width:= size.__property_get_x;
  height:= size.__property_get_y;
  buf_pos:=0;

  for y := offY to offY + height - 1  do
  begin
    RowPtr:= formMain.imgPreview.Bitmap.ScanLine[y];
    Inc(RowPtr, offX);
    for x := 0 to width - 1  do
    begin
      RowPtr.rgbReserved:= (buf[buf_pos] div $1000000);
      RowPtr.rgbRed:= ((buf[buf_pos] mod $1000000) div $10000);
      RowPtr.rgbGreen:= ((buf[buf_pos] mod $10000) div $100);
      RowPtr.rgbBlue:= (buf[buf_pos] mod $100);
      Inc(RowPtr);
      Inc(buf_pos);
    end;
  end;

  formMain.imgPreview.Refresh;
  formMain.imgPreview.Update;
end;

但这不是真的,似乎是灰色的

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-02-13 10:16:56

你好像把你的频道搞混了。当您说输入是ARGB时,您将其视为RGBA。无论如何,使用divmod的代码都是无效的。按位变换是一种惯用的方式。

对于ARGB输入,您可以这样做:

代码语言:javascript
复制
procedure ARGBtoColorChannels(ARGB: DWORD; out A, R, G, B: Byte);
begin
  A := Byte(ARGB);
  R := Byte(ARGB shr 8);
  G := Byte(ARGB shr 16);
  B := Byte(ARGB shr 24);
end;

或者,如果您从RGBA开始,则如下所示:

代码语言:javascript
复制
procedure RGBAtoColorChannels(RGBA: DWORD; out A, R, G, B: Byte);
begin
  R := Byte(RGBA);
  G := Byte(RGBA shr 8);
  B := Byte(RGBA shr 16);
  A := Byte(RGBA shr 24);
end;

这些都是小的endian版本,因为在编写本报告时,Delphi只针对小endian机器。

如果您正在寻找一个将ARGB转换为RGBA的函数,那么您可以这样做:

代码语言:javascript
复制
function ARGBtoRGBA(ARGB: DWORD): DWORD;
var
  A, R, G, B: Byte;
begin
  ARGBtoColorChannels(ARGB, A, R, G, B);
  Result := R or (G shl 8) or (B shl 16) or (A shl 24);
end;

为了完整起见,情况正好相反:

代码语言:javascript
复制
function RGBAtoARGB(RGBA: DWORD): DWORD;
var
  A, R, G, B: Byte;
begin
  RGBAtoColorChannels(RGBA, A, R, G, B);
  Result := A or (R shl 8) or (G shl 16) or (B shl 24);
end;

为了让您知道该做什么,您需要了解buf是什么。是ARGB还是RGBA?假设它是ARGB,考虑到您问题的内容,您将尝试复制到RowPtr,这似乎也是ARGB。在这种情况下,您可以将颜色如下所示:

代码语言:javascript
复制
PInteger(RowPtr)^ := buf[buf_pos];

我还强烈建议您更改buf参数的类型。在这里,无符号类型更好,因为您可能需要执行按位操作。此外,您正在通过堆栈复制整个数组,这是非常低效率的。对于大位图,您将遭受堆栈溢出。相反,该参数应该是:

代码语言:javascript
复制
const buf: array of DWORD;

代码语言:javascript
复制
const buf: array of Cardinal;

使用const意味着传递对数组的引用,而不是副本。

您最好避免使用PRGBQuad,并声明RowPtrPCardinal类型。

然后你可以这样分配:

代码语言:javascript
复制
RowPtr^ := buf[buf_pos];

在这一点上,您不需要做逐像素。您可以使用Move复制整个scanline,因为这是一个简单的blit。

代码语言:javascript
复制
for y := offY to offY + height - 1  do
begin
  RowPtr := formMain.imgPreview.Bitmap.ScanLine[y];
  Inc(RowPtr, offX);
  Move(buf[buf_pos], RowPtr^, width*SizeOf(RowPtr^));
  Inc(buf_pos, width);
end;

RefreshUpdate打电话似乎毫无意义。我也不确定您是否需要打电话,但如果需要,只需调用Invalidate就行了!

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28497138

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档