Fórum como redimensionar imagem? #267731
08/02/2005
0
gostaria de redimensionar uma imagem antes de grava-la num banco... de forma que todas as imagens entrem num tamanho padrão...
lembrando que o objetivo é evitar que imagem com tamanho grande seja salvas e ocupem muito espaço!
como posso fazer?
obrigado...
Mrcdlf
Curtir tópico
+ 0Posts
08/02/2005
Ivanh
Na revista 58, tem um artigo sobre criação de jogos, talvez ajude...
Gostei + 0
09/02/2005
Marcelo Saviski
Gostei + 0
21/02/2005
Mrcdlf
pelo q pesquisei o BitBlt não faz esse tipo de coisa... pelo q entendi ele só copia a imagem como ela é...
se eu estiver errado, por favor, me corrijam
agora achei um exemplo sim, só q ele deixa a imagem numa qualidade muito ruim será q é possivel melhorar isso?
o codigo q usei foi o seguinte:
Código:
function PadronizaTamanho(Imagem: TGraphic; W, H: Integer; Tipo: TGraphicClass = nil): TGraphic;
var
B: TBitmap;
begin
B := TBitmap.Create;
try
B.Width := W;
B.Height := H;
B.Canvas.StretchDraw(Rect(0, 0, W, H), Imagem);
if Tipo = nil then
Result := TGraphic(Imagem.ClassType.Create)
else
Result := Tipo.Create;
Result.Assign(B);
finally
B.Free;
end;
end;
Exemplo de uso:
Código:
procedure TForm1.Button1Click(Sender: TObject);
var
Nova: TGraphic;
begin
Nova := PadronizaTamanho(Image1.Picture.Graphic, 80, 80, TJPEGImage);
try
Image2.Picture.Graphic := Nova;
finally
Nova.Free;
end;
end;
Gostei + 0
21/02/2005
Marcelo Saviski
tem como melhorar sim, se vc tiver a jcl (JEDI Code Library), pode usar essa unit: http://www.koders.com/delphi/fid1DF4D91A23AF9688471FA339A4E276A44C33099A.aspx
ou a GR32 (Graphics32), que tem várias funções para isso, (DoStretch) http://www.koders.com/delphi/fid683F1F4625F55765FD95866D982B69D65D332E78.aspx
tem só essa função DoStrech, um pouco alterada aqui: http://www.experts-exchange.com/Programming/Programming_Languages/Delphi/Q_10211552.html
e tem esse exemplo que peguei na net um vez, mas não lembro aonde:
{
Before importing an image (jpg) into a database,
I would like to resize it (reduce its size) and
generate the corresponding smaller file. How can I do this?
Load the JPEG into a bitmap, create a new bitmap
of the size that you want and pass them both into
SmoothResize then save it again ...
there´s a neat routine JPEGDimensions that
gets the JPEG dimensions without actually loading the JPEG into a bitmap,
saves loads of time if you only need to test its size before resizing.
}
uses
JPEG;
type
TRGBArray = array[Word] of TRGBTriple;
pRGBArray = ^TRGBArray;
{---------------------------------------------------------------------------
-----------------------}
procedure SmoothResize(Src, Dst: TBitmap);
var
x, y: Integer;
xP, yP: Integer;
xP2, yP2: Integer;
SrcLine1, SrcLine2: pRGBArray;
t3: Integer;
z, z2, iz2: Integer;
DstLine: pRGBArray;
DstGap: Integer;
w1, w2, w3, w4: Integer;
begin
Src.PixelFormat := pf24Bit;
Dst.PixelFormat := pf24Bit;
if (Src.Width = Dst.Width) and (Src.Height = Dst.Height) then
Dst.Assign(Src)
else
begin
DstLine := Dst.ScanLine[0];
DstGap := Integer(Dst.ScanLine[1]) - Integer(DstLine);
xP2 := MulDiv(pred(Src.Width), $10000, Dst.Width);
yP2 := MulDiv(pred(Src.Height), $10000, Dst.Height);
yP := 0;
for y := 0 to pred(Dst.Height) do
begin
xP := 0;
SrcLine1 := Src.ScanLine[yP shr 16];
if (yP shr 16 < pred(Src.Height)) then
SrcLine2 := Src.ScanLine[succ(yP shr 16)]
else
SrcLine2 := Src.ScanLine[yP shr 16];
z2 := succ(yP and $FFFF);
iz2 := succ((not yp) and $FFFF);
for x := 0 to pred(Dst.Width) do
begin
t3 := xP shr 16;
z := xP and $FFFF;
w2 := MulDiv(z, iz2, $10000);
w1 := iz2 - w2;
w4 := MulDiv(z, z2, $10000);
w3 := z2 - w4;
DstLine[x].rgbtRed := (SrcLine1[t3].rgbtRed * w1 +
SrcLine1[t3 + 1].rgbtRed * w2 +
SrcLine2[t3].rgbtRed * w3 + SrcLine2[t3 + 1].rgbtRed * w4) shr 16;
DstLine[x].rgbtGreen :=
(SrcLine1[t3].rgbtGreen * w1 + SrcLine1[t3 + 1].rgbtGreen * w2 +
SrcLine2[t3].rgbtGreen * w3 + SrcLine2[t3 + 1].rgbtGreen * w4) shr 16;
DstLine[x].rgbtBlue := (SrcLine1[t3].rgbtBlue * w1 +
SrcLine1[t3 + 1].rgbtBlue * w2 +
SrcLine2[t3].rgbtBlue * w3 +
SrcLine2[t3 + 1].rgbtBlue * w4) shr 16;
Inc(xP, xP2);
end;
Inc(yP, yP2);
DstLine := pRGBArray(Integer(DstLine) + DstGap);
end;
end;
end;
{---------------------------------------------------------------------------
-----------------------}
function LoadJPEGPictureFile(Bitmap: TBitmap; FilePath, FileName: string): Boolean;
var
JPEGImage: TJPEGImage;
begin
if (FileName = ´´) then // No FileName so nothing
Result := False //to load - return False...
else
begin
try // Start of try except
JPEGImage := TJPEGImage.Create; // Create the JPEG image... try // now
try // to load the file but
JPEGImage.LoadFromFile(FilePath + FileName);
// might fail...with an Exception.
Bitmap.Assign(JPEGImage);
// Assign the image to our bitmap.Result := True;
// Got it so return True.
finally
JPEGImage.Free; // ...must get rid of the JPEG image. finally
end;
except
Result := False; // Oops...never Loaded, so return False.
end;
end;
end;
{---------------------------------------------------------------------------
-----------------------}
function SaveJPEGPictureFile(Bitmap: TBitmap; FilePath, FileName: string;
Quality: Integer): Boolean;
begin
Result := True;
try
if ForceDirectories(FilePath) then
begin
with TJPegImage.Create do
begin
try
Assign(Bitmap);
CompressionQuality := Quality;
SaveToFile(FilePath + FileName);
finally
Free;
end;
end;
end;
except
raise;
Result := False;
end;
end;
{---------------------------------------------------------------------------
-----------------------}
procedure ResizeImage(FileName: string; MaxWidth: Integer);
var
OldBitmap: TBitmap;
NewBitmap: TBitmap;
aWidth: Integer;
begin
OldBitmap := TBitmap.Create;
try
if LoadJPEGPictureFile(OldBitmap, ExtractFilePath(FileName),
ExtractFileName(FileName)) then
begin
aWidth := OldBitmap.Width;
if (OldBitmap.Width > MaxWidth) then
begin
aWidth := MaxWidth;
NewBitmap := TBitmap.Create;
try
NewBitmap.Width := MaxWidth;
NewBitmap.Height := MulDiv(MaxWidth, OldBitmap.Height, OldBitmap.Width);
SmoothResize(OldBitmap, NewBitmap);
RenameFile(FileName, ChangeFileExt(FileName, ´.$$$´));
if SaveJPEGPictureFile(NewBitmap, ExtractFilePath(FileName),
ExtractFileName(FileName), 75) then
DeleteFile(ChangeFileExt(FileName, ´.$$$´))
else
RenameFile(ChangeFileExt(FileName, ´.$$$´), FileName);
finally
NewBitmap.Free;
end;
end;
end;
finally
OldBitmap.Free;
end;
end;
{---------------------------------------------------------------------------
-----------------------}
function JPEGDimensions(Filename : string; var X, Y : Word) : boolean;
var
SegmentPos : Integer;
SOIcount : Integer;
b : byte;
begin
Result := False;
with TFileStream.Create(Filename, fmOpenRead or fmShareDenyNone) do
begin
try
Position := 0;
Read(X, 2);
if (X <> $D8FF) then
exit;
SOIcount := 0;
Position := 0;
while (Position + 7 < Size) do
begin
Read(b, 1);
if (b = $FF) then begin
Read(b, 1);
if (b = $D8) then
inc(SOIcount);
if (b = $DA) then
break;
end;
end;
if (b <> $DA) then
exit;
SegmentPos := -1;
Position := 0;
while (Position + 7 < Size) do
begin
Read(b, 1);
if (b = $FF) then
begin
Read(b, 1);
if (b in [$C0, $C1, $C2]) then
begin
SegmentPos := Position;
dec(SOIcount);
if (SOIcount = 0) then
break;
end;
end;
end;
if (SegmentPos = -1) then
exit;
if (Position + 7 > Size) then
exit;
Position := SegmentPos + 3;
Read(Y, 2);
Read(X, 2);
X := Swap(X);
Y := Swap(Y);
Result := true;
finally
Free;
end;
end;
end;
vc usaria essas funções no lugar do BitBtl, ou StretchDraw para ter maois qualidade no redimencionamento
Ainda tem mais estes dois exemplos:
http://www.swissdelphicenter.ch/en/showcode.php?id=1896
http://www.swissdelphicenter.ch/en/showcode.php?id=1463
Gostei + 0
21/02/2005
Pistesil
Eu uso essa funcao e ela funcionou perfeitamente para mim..
Gostei + 0
21/02/2005
Mrcdlf
Eu uso essa funcao e ela funcionou perfeitamente para mim..[/quote:1018c0d141]
por incrivel que pareça essa função não funcionou... a qualidade continou ruim...
mais teve um link q tem uma função que funciono perfeitamente... apersar de aki tersido um pouco lenta...
a função está abaixo para facilitar...
valeu ai pela ajuda!!!!
procedure TFormConvertir.ResizeBitmap(imgo, imgd: TBitmap; nw, nh: Integer);
var
xini, xfi, yini, yfi, saltx, salty: single;
x, y, px, py, tpix: integer;
PixelColor: TColor;
r, g, b: longint;
function MyRound(const X: Double): Integer;
begin
Result := Trunc(x);
if Frac(x) >= 0.5 then
if x >= 0 then Result := Result + 1
else
Result := Result - 1;
// Result := Trunc(X + (-2 * Ord(X < 0) + 1) * 0.5);
end;
begin
// Set target size
imgd.Width := nw;
imgd.Height := nh;
// Calcs width & height of every area of pixels of the source bitmap
saltx := imgo.Width / nw;
salty := imgo.Height / nh;
yfi := 0;
for y := 0 to nh - 1 do
begin
// Set the initial and final Y coordinate of a pixel area
yini := yfi;
yfi := yini + salty;
if yfi >= imgo.Height then yfi := imgo.Height - 1;
xfi := 0;
for x := 0 to nw - 1 do
begin
// Set the inital and final X coordinate of a pixel area
xini := xfi;
xfi := xini + saltx;
if xfi >= imgo.Width then xfi := imgo.Width - 1;
// This loop calcs del average result color of a pixel area
// of the imaginary grid
r := 0;
g := 0;
b := 0;
tpix := 0;
for py := MyRound(yini) to MyRound(yfi) do
begin
for px := MyRound(xini) to MyRound(xfi) do
begin
Inc(tpix);
PixelColor := ColorToRGB(imgo.Canvas.Pixels[px, py]);
r := r + GetRValue(PixelColor);
g := g + GetGValue(PixelColor);
b := b + GetBValue(PixelColor);
end;
end;
// Draws the result pixel
imgd.Canvas.Pixels[x, y] :=
rgb(MyRound(r / tpix),
MyRound(g / tpix),
MyRound(b / tpix)
);
end;
end;
end;
Gostei + 0
21/02/2005
Beppe
PS: A primeira função eu que escrevi e funciona muito bem para fotografias. btw, quem faz o serviço bruto é o Delphi/Windows.
Gostei + 0
21/02/2005
Mrcdlf
a primeira função aki simplesmente não teve resultado nenhum...
pode ser que eu tenha feito algo de errado...
Gostei + 0
21/02/2005
Beppe
:shock:
Fala de PadronizaTamanho? Tanto pra mim, como o desenvolvedor que pediu a função, deu certo...
Gostei + 0
21/02/2005
Mrcdlf
:shock:
Fala de PadronizaTamanho? Tanto pra mim, como o desenvolvedor que pediu a função, deu certo...[/quote:fe7164278c]
funcionar funciono só q a qualidade continuou ruim...
bem de qualquer forma eu posso ter feito algo de errado tb!
mais a função que falei funcionou perfeitamente...
valeu!
Gostei + 0
21/02/2005
Beppe
Pode hospedar no ImageShack.us ou me mandar por e-mail.
T+
Gostei + 0
21/02/2005
Beppe
procedure ResizeBitmap32(imgo, imgd: TBitmap; nw, nh: Integer); var xini, xfi, yini, yfi, saltx, salty: single; x, y, px, py, tpix: integer; PixelColor: TColor; r, g, b: longint; P1, P2: PChar; begin // Set target size imgd.Width := nw; imgd.Height := nh; P1 := imgo.ScanLine[imgo.Height - 1]; P2 := imgd.ScanLine[imgd.Height - 1]; // Calcs width & height of every area of pixels of the source bitmap saltx := imgo.Width / nw; salty := imgo.Height / nh; yfi := 0; for y := 0 to nh - 1 do begin // Set the initial and final Y coordinate of a pixel area yini := yfi; yfi := yini + salty; if yfi >= imgo.Height then yfi := imgo.Height - 1; xfi := 0; for x := 0 to nw - 1 do begin // Set the inital and final X coordinate of a pixel area xini := xfi; xfi := xini + saltx; if xfi >= imgo.Width then xfi := imgo.Width - 1; // This loop calcs del average result color of a pixel area // of the imaginary grid r := 0; g := 0; b := 0; tpix := 0; for py := Round(yini) to Round(yfi) do begin for px := Round(xini) to Round(xfi) do begin Inc(tpix); PixelColor := (PColor(P1 + ((imgo.Height - py - 1) * imgo.Width + px)*4)^); r := r + PixelColor shr 16 and $ff; g := g + PixelColor shr 08 and $ff; b := b + PixelColor shr 00 and $ff; end; end; // Draws the result pixel // PColor(P2 + ((imgd.Height - y - 1) * imgd.Width + x)*4)^ := rgb(Round(r / tpix),Round(g / tpix),Round(b / tpix)); imgd.Canvas.Pixels[x, y] := rgb((r div tpix),(g div tpix),(b div tpix)); end; end; end;
Reescrevi umas partes da rotina, ficou bem melhor, embora eu pudesse fazer ainda melhor.
Gostei + 0
22/02/2005
Mrcdlf
essa ultima função que vc me mandou está dando um erro aqui...
me fala seu e-mail que vou lhe mandar a imagem.
Gostei + 0
22/02/2005
Beppe
Adiciona um SeuBitmap.PixelFormat := pf32bit;
Ou troque um *4 por *3 para 24bit. Não testei, mas pode funcionar.
Gostei + 0
22/02/2005
Mrcdlf
bem aqui ainda não resolveu o problema
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)