• Welcome to Vampyre Imaging Library Forum. Please login or sign up.
 

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Topics - heju

1
Hi,

somehow, when loading a rgb bitmap with alpha channel and writing it back to bitmap the result is very blueish and the resulting bitmap has no alpha channel, seems as if the alpha channel is interpreted as blue somewhere.

img.CreateFromFile('rgb128alpha.bmp');
img.SaveToFile('out.bmp');


I checked the bytes after creating, here everything seems correct, problem should be in the save procedure.

When trying to save to PNG, the resulting png has alpha, but is blueish as well.

Hope I find some more time to give more detailed description...

Greetings&Bye
2
Hi,

when converting a rgb bmp with alpha channel to ifGray8, I noted that the pixel values in the final image are not as expected.

I think the problem could be here:
The source is read using PColor24Rec(Src), however in memory there is the alpha byte first (not the blue byte). Therefore the alpha channel is interpreted as blue channel. As the Src is incremented by 4 which is correct, the pixels do not get mixed up totally. 


procedure ChannelToGray(NumPixels: LongInt; Src, Dst: PByte; SrcInfo,
  DstInfo: PImageFormatInfo);
var
  I: LongInt;
  Pix64: TColor64Rec;
  Alpha: Word;
begin
  // two most common conversions (R8G8B8->Gray8 nad A8R8G8B8->Gray8)
  // are made separately from general conversions to make them faster
  if (SrcInfo.BytesPerPixel in [3, 4]) and (DstInfo.Format = ifGray8) then
    for I := 0 to NumPixels - 1 do
    begin
      Dst^ := Round(GrayConv.R * PColor24Rec(Src).R + GrayConv.G * PColor24Rec(Src).G +
        GrayConv.B * PColor24Rec(Src).B);
      Inc(Src, SrcInfo.BytesPerPixel);
      Inc(Dst, DstInfo.BytesPerPixel);
    end
  else 
[...]
                                 


One ugly workaround which just disregards the alpha channel is to increment Src by one before entering the loop in case we have 4 bytes per pixel, then the RGB values are not mixed up at least.

Greetings & bye
3
Hi,

while converting gray 8bit images to float 32bit and back to gray 8 bit I noted that the intensity values dramatically change:

"in128.bmp" is a grayscale bitmap with pixel values of 128

img.CreateFromFile('in128.bmp');
img.Format:=ifGray8;
img.Format:=ifR32F;
img.Format:=ifGray8;
img.SaveToFile('out.bmp');


Now in the "out.bmp" image the pixel values are only 38.

As this is a bit of a problem for my application, I investigated a bit: The root cause seems to be here:
procedure FloatToGray(NumPixels: LongInt; Src, Dst: PByte; SrcInfo,
  DstInfo: PImageFormatInfo);
var
  I: LongInt;
  PixF: TColorFPRec;
  Gray: TColor64Rec;
  Alpha: Word;
begin
  for I := 0 to NumPixels - 1 do
  begin
    FloatGetSrcPixel(Src, SrcInfo, PixF);
    ClampFloatPixel(PixF);

    // alpha is saved from source pixel to Alpha,
    // Gray value is computed and set to highest word of Pix64 so
    // Pix64.Color contains grayscale value scaled to 64 bits
    Alpha := ClampToWord(Round(PixF.A * 65535.0));
    Gray.A := ClampToWord(Round((GrayConv.R * PixF.R + GrayConv.G * PixF.G +
      GrayConv.B * PixF.B) * 65535.0));

    GraySetDstPixel(Dst, DstInfo, Gray, Alpha);
    Inc(Src, SrcInfo.BytesPerPixel);
    Inc(Dst, DstInfo.BytesPerPixel);
  end;
end;


Even the float image is single channel, the RGB-> gray conversion is calculated, reducing the pixel values (there is only intensity in red channel and this gets multiplied with GrayConv.R factor.

I workarounded the behaviour using the following approach (don't know if there are side effects). However now the value after conversion is the same as before:
(sry, you have to scroll down a bit maybe ;) )

procedure FloatToGray(NumPixels: LongInt; Src, Dst: PByte; SrcInfo,
  DstInfo: PImageFormatInfo);
var
  I: LongInt;
  PixF: TColorFPRec;
  Gray: TColor64Rec;
  Alpha: Word;
begin
  for I := 0 to NumPixels - 1 do
  begin
    FloatGetSrcPixel(Src, SrcInfo, PixF);
    ClampFloatPixel(PixF);

    // alpha is saved from source pixel to Alpha,
    // Gray value is computed and set to highest word of Pix64 so
    // Pix64.Color contains grayscale value scaled to 64 bits
    Alpha := ClampToWord(Round(PixF.A * 65535.0));
    if SrcInfo.ChannelCount =1 then
      Gray.A := ClampToWord(Round(PixF.R * 65535.0))
    else
      Gray.A := ClampToWord(Round((GrayConv.R * PixF.R + GrayConv.G * PixF.G +
        GrayConv.B * PixF.B) * 65535.0));

    GraySetDstPixel(Dst, DstInfo, Gray, Alpha);
    Inc(Src, SrcInfo.BytesPerPixel);
    Inc(Dst, DstInfo.BytesPerPixel);
  end;
end;


Bye...
SMF spam blocked by CleanTalk