怎样从image中获得Stream ( 积分: 100 )

  • 主题发起人 主题发起人 刘邦
  • 开始时间 开始时间

刘邦

Unregistered / Unconfirmed
GUEST, unregistred user!
to dawnsong
我想将你的jpg对象直接从image1中获取图片,通过jpg旋转后再加载到image1中,不经过保存文件的过程:以下是代码可是运行不过去,应该怎样修改请指教:
procedure TFORMREADER.N903Click(Sender: TObject);
var
jpg:TJPEGImage;
imageStream:TStream;
begin
jpg :=TJPEGImage.Create;
imageStream:=Tstream.Create;
try
image1.Picture.Icon.SaveToStream(imageStream);//我的意图是将图片保存到流中
jpg.LoadFromStream(imageStream);//jpg从流中加载
//jpg.LoadFromFile('test.jpg');
//旋转90度
RotateJpg(jpg,90);//旋转
jpg.JPEGNeeded;
jpg.SaveToStream(imageStream);//再保存到流中
image1.Picture.Graphic.LoadFromStream(ImageStream);//image1从流中加载图片

finally
jpg.Destroy;
end;
 
to dawnsong
我想将你的jpg对象直接从image1中获取图片,通过jpg旋转后再加载到image1中,不经过保存文件的过程:以下是代码可是运行不过去,应该怎样修改请指教:
procedure TFORMREADER.N903Click(Sender: TObject);
var
jpg:TJPEGImage;
imageStream:TStream;
begin
jpg :=TJPEGImage.Create;
imageStream:=Tstream.Create;
try
image1.Picture.Icon.SaveToStream(imageStream);//我的意图是将图片保存到流中
jpg.LoadFromStream(imageStream);//jpg从流中加载
//jpg.LoadFromFile('test.jpg');
//旋转90度
RotateJpg(jpg,90);//旋转
jpg.JPEGNeeded;
jpg.SaveToStream(imageStream);//再保存到流中
image1.Picture.Graphic.LoadFromStream(ImageStream);//image1从流中加载图片

finally
jpg.Destroy;
end;
 
将RotateJpg方法也贴上来
 
to dawnsong 另外能不能将程序中代码后面加斜杠的给注释一下,谢谢
procedure TForm1.Image1DblClick(Sender: TObject);
var
jpg:TJPEGImage;
begin
jpg :=TJPEGImage.Create;
try
jpg.LoadFromFile('test.jpg');
RotateJpg(jpg,90);
jpg.JPEGNeeded;////
jpg.SaveToFile('log1.jpg');

Image1.Picture.Bitmap.FreeImage;
jpg.DIBNeeded;//
Image1.Canvas.StretchDraw(Image1.ClientRect,jpg);//
image1.Picture.LoadFromFile('log1.JPG');
finally
jpg.Destroy;
end;
end;
 
procedure RotateBmp(bmp: TBitmap; Center: TPoint; angle: Integer);
var
tmpbmp: TBitmap;
i, j, x, y, px, py: Integer;
cAngle, sAngle: Extended;
p1, p2 :PByteArray;
NextLine:Integer;
pOrigin1,pOrigin2:PByte;
logI,logJ:Integer;
begin
while angle < 0 do Inc(angle,360);
angle := angle mod 360;
sAngle := sin(- angle * pi / 180);
cAngle := cos(- angle * pi / 180);

tmpbmp := tbitmap.create;
try
tmpbmp.assign(bmp);
tmpbmp.PixelFormat :=pf24bit;
pOrigin1 := tmpbmp.scanline[0];
NextLine := Integer(tmpbmp.scanline[1]) -Integer(pOrigin1);//增量,此处的存储结构为负
//tmpbmp.SaveToFile('log.bmp');

bmp.FreeImage;
bmp.Width :=tmpbmp.Width;
bmp.Height:=tmpbmp.Height;
bmp.PixelFormat :=pf24bit;
bmp.Canvas.FillRect(bmp.Canvas.ClipRect);
pOrigin2 := bmp.scanline[0];

try
Integer(p1) :=Integer(pOrigin1);
for i := 0 to tmpbmp.height - 1 do
begin
py := 2 * (i - center.y) - 1;
for j := 0 to tmpbmp.width - 1 do
begin
px := 2 * (j - center.x) - 1;
x := (round(px * cAngle - py * sAngle) - 1) div 2 + center.x;
y := (round(px * sAngle + py * cAngle) - 1) div 2 + center.y;
if (x>=0)and(x<tmpbmp.width)and(y>=0)and(y<tmpbmp.height) then
begin
Integer(p2) := Integer(pOrigin2) + y *NextLine +x *3;
p2[0] :=p1[0];
p2[1] :=p1[1];
p2[2] :=p1[2];
end;
Integer(p1) :=Integer(p1) +3;
logJ :=j;
end;
Integer(p1) :=Integer(pOrigin1) +NextLine *i;
logI :=i;
end;
except on e:Exception do begin
ShowMessage(IntToStr(logI));
ShowMessage(IntToStr(logJ));
end;
end;
finally
tmpbmp.Destroy;
end;
end;

procedure RotateJpg(var jpg:TJPEGImage;const angle: Integer);
var
bmp :TBitmap;
center:TPoint;
begin
bmp :=TBitmap.Create;
try
jpg.DIBNeeded;
bmp.Width :=jpg.Width;
bmp.Height:=jpg.Height;
bmp.Canvas.StretchDraw(bmp.Canvas.ClipRect,jpg);
center.X :=(bmp.Canvas.ClipRect.Right -bmp.Canvas.ClipRect.Left) div 2;
center.Y :=(bmp.Canvas.ClipRect.Bottom-bmp.Canvas.ClipRect.Top) div 2;
RotateBmp(bmp,center,angle);
jpg.Assign(bmp);
finally
bmp.Destroy;
end;
end;
 
image1.Picture.Icon.SaveToStream(imageStream);//我的意图是将图片保存到流中
jpg.LoadFromStream(imageStream);//jpg从流中加载
=========
直接改成jpg.Assign(image1.Picture.Bitmap);就可以了,并不需要再通过流来做中介的
 
所以
jpg.SaveToStream(imageStream);//再保存到流中
image1.Picture.Graphic.LoadFromStream(ImageStream);//image1从流中加载图片
=============
这两个也不需要了,直接image1.Picture.Bitmap.Assign(jpg);即可
 
to islet8 按你所说修改了程序如下:
procedure TFORMREADER.N903Click(Sender: TObject);
var
jpg:TJPEGImage;
imageStream:TStream;
begin
jpg :=TJPEGImage.Create;
imageStream:=Tstream.Create;
try
jpg.Assign(image1.Picture.Bitmap);
//旋转90度
RotateJpg(jpg,90);
jpg.JPEGNeeded;
Image1.Picture.Bitmap.FreeImage;
jpg.DIBNeeded;
Image1.Canvas.StretchDraw(Image1.ClientRect,jpg);
image1.Picture.Bitmap.Assign(jpg);
finally
jpg.Destroy;
end;
end;

可是出现错误:scan line index out of range
是在TformReader.RotateBmp(bmp: TBitmap; Center: TPoint; angle: Integer);中的
pOrigin1 := tmpbmp.scanline[0];代码行出现的,为什么?
 
你这样是不行的,因为格式不匹配
 
可是出现错误:scan line index out of range
是在TformReader.RotateBmp(bmp: TBitmap; Center: TPoint; angle: Integer);中的
pOrigin1 := tmpbmp.scanline[0];代码行出现的,为什么?

这是因为jpg.Assign(image1.Picture.Bitmap);并没有把图像给复制过来
 
procedure TForm1.Image1DblClick(Sender: TObject);
var
jpg:TJPEGImage;
begin
jpg :=TJPEGImage.Create;
try
//jpg.LoadFromFile('test.jpg');
//Image1.Picture.SaveToClipboardFormat(CF_BITMAP,Image1.Picture.Bitmap.Handle,nil);
jpg.Assign(Image1.Picture.Graphic);

//旋转30度
RotateJpg(jpg,90);
jpg.JPEGNeeded;
jpg.SaveToFile('log1.jpg');
//Image1.Picture.Bitmap.FreeImage;
//Image1.Picture.Bitmap:=nil;
//Image1.Canvas.StretchDraw(Image1.ClientRect,jpg);
Image1.Picture.Bitmap.Assign(jpg);
finally
jpg.Destroy;
end;
end;
 
如上就没问题了
 
你似乎应该先判断image1.Picture.Graphic是TJPEGImage还是TBitmap
对于TJPEGImage的就直接jpg.Assign(image1.Picture.Graphic),如果是TBitmap才能通过我上面说的方法做
 
呵呵[:D]dawnsong不错
 
太太太太太太太感谢了,尤其是dawnsong,如果哪一天能见面,我一定请你吃饭[:D]
另外能否解释一下:
jpg.JPEGNeeded;////

jpg.DIBNeeded;//
Image1.Canvas.StretchDraw(Image1.ClientRect,jpg);//
这几句的意思
 
jpg.JPEGNeeded;//将内存中的数据压缩为jpeg

jpg.DIBNeeded;//将内存中的数据解压缩为bmp
 
to dawnsong 我将image1.picture.savetoFile()
可是却出现了保存的图片很大例如原来的600k,保存后2MB,并且打不开,为什么?
 
image1.picture.savetoFile()
可是却出现了保存的图片很大例如原来的600k,保存后2MB,并且打不开,为什么?

这个是否保存为了Bmp?这样是会增大很多
 

Similar threads

D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
I
回复
0
查看
641
import
I
后退
顶部