一个图片长方形的,我们正面看过去的时候(拍照拍下来),是一个长方形,但是我们侧面看过去的时候还是拍照拍下来,图片就看上去就变化了,我需要获得从侧面看过去的时候的图片效果图,哪位知道或有现成的算法提供一下,非常感谢,高分相送,分不够可以再说1千都可以,很急
解决方案 »
- 求指点,DELPHI中级,转C/C+,向病毒安全行业发展,诚心请教。
- 急急急!!!请问 如何打印 000XXX 这样格式的数据
- Delphi 在开发下一代互联网和网络会议上是否已经落伍?
- 请问在美国等IT发达国家有像CSDN BBS这样的网站吗?介绍几个有名的啊
- 有哪位是计算机毕业的,但又在银行工作的,请进
- combobox如何响应滚轮事件?解决立即给分
- 客户端安装什么之后就可以连接到ORACLE数据库了?
- 关于关于窗体CloseQuery事件的问题!
- delphi7 聊天室的源码出现"undeclared identifier athread",为什么啊?
- 如何獲得Adoconnect的connectstring.
- 急招Delphi程序员、asp
- 如何在Delphi2005中继承第三方控件来开发自定义控件?
unit QQCanvas3D;interface
uses Windows,SysUtils,Graphics;
const
SEEFAR=5000;//眼睛可看到的最远距离type
T3DPoint=record
x,y,z:Integer;
end;
T2DPoint=record
x,y:Integer;
end;
TCanvas3D=class
private
FViewWidth: Integer;
FViewHeight: Integer;
FOrigin: T3DPoint;
FFCanvas2D: TCanvas;
procedure SetViewHeight(const Value: Integer);
procedure SetViewWidth(const Value: Integer);
procedure SetFCanvas2D(const Value: TCanvas);
function GetPixels(x, y, z: Integer): TColor;
procedure SetPixels(x, y, z: Integer; const Value: TColor);
function GetBrush: TBrush;
function GetPen: TPen;
procedure SetBrush(const Value: TBrush);
procedure SetPen(const Value: TPen);
procedure SetOrigin(const Value: T3DPoint);
protected
function Point3DTo2D(const Point:T3DPoint):T2DPoint;overload;
function Point3DTo2D(x,y,z:Integer):T2DPoint;overload;
public
constructor Create(Canvas:TCanvas);
property FCanvas2D:TCanvas read FFCanvas2D write SetFCanvas2D; procedure MoveTo(x,y,z:Integer);
procedure LineTo(x,y,z:Integer);
procedure Arc(x,y,z,r:Integer;StartRadian,EndRadian:Double);
procedure Sphere(x,y,z,r:Integer;hs:Integer=100;vs:Integer=100);
property Pixels[x,y,z:Integer]:TColor read GetPixels write SetPixels;
property Pen:TPen read GetPen write SetPen;
property Brush:TBrush read GetBrush write SetBrush;
property Origin:T3DPoint read FOrigin write SetOrigin;
property ViewWidth:Integer read FViewWidth write SetViewWidth;
property ViewHeight:Integer read FViewHeight write SetViewHeight;
end;implementation
const
RadianCount=7200;
PI=3.1415926;
PI2=2*PI;var
FSinArray:array[0..RadianCount] of Double;
FCosArray:array[0..RadianCount] of Double;
FRadianStep:Double;{ TCanvas3D }procedure TCanvas3D.Arc(x, y, z, r: Integer; StartRadian, EndRadian: Double);
var
bt,et,tx,ty:Integer;
tRadian:Double;begin
if StartRadian>EndRadian then
begin
tRadian:=StartRadian;
StartRadian:=EndRadian;
EndRadian:=tRadian;
end;
if EndRadian-StartRadian>PI2 then EndRadian:=StartRadian+PI2;
bt:=Round(StartRadian/FRadianStep);
et:=Round(EndRadian/FRadianStep);
tx:=Round(FCosArray[bt]*r+x);
ty:=Round(FSinArray[bt]*r+y);
with Point3DTo2D(tx,ty,z) do
begin
FCanvas2D.MoveTo(x,y);
end;
inc(bt);
while bt<et do
begin
tx:=Round(FCosArray[bt]*r+x);
ty:=Round(FSinArray[bt]*r+y);
with Point3DTo2D(tx,ty,z) do
begin
FCanvas2D.LineTo(x,y);
end;
inc(bt);
end;
end;constructor TCanvas3D.Create(Canvas:TCanvas);
begin
FCanvas2D:=Canvas;
FViewWidth:=400;
FViewHeight:=300;
FOrigin.X:=0;
FOrigin.Y:=0;
FOrigin.Z:=0;
end;
function TCanvas3D.GetBrush: TBrush;
begin
Result:=FCanvas2D.Brush;
end;function TCanvas3D.GetPen: TPen;
begin
Result:=FCanvas2D.Pen;
end;function TCanvas3D.GetPixels(x, y, z: Integer): TColor;
begin
with Point3DTo2D(x,y,z) do
begin
Result:=FCanvas2D.Pixels[x,y];
end;
end;procedure TCanvas3D.LineTo(x, y, z: Integer);
begin
with Point3DTo2D(x,y,z) do
begin
FCanvas2D.LineTo(x,y);
end;
end;procedure TCanvas3D.MoveTo(x, y, z: Integer);
begin
with Point3DTo2D(x,y,z) do
begin
FCanvas2D.MoveTo(x,y);
end;
end;function TCanvas3D.Point3DTo2D(const Point: T3DPoint): T2DPoint;
begin
Result.x:=Round(Point.x*(1-(Point.z+Origin.z)/SEEFAR))+Origin.X;
Result.y:=Round(Point.y*(1-(Point.z+Origin.z)/SEEFAR))+Origin.Y;
end;function TCanvas3D.Point3DTo2D(x, y, z: Integer): T2DPoint;
begin
Result.x:=Round(x*(1-(z+Origin.z)/SEEFAR))+Origin.X;
Result.y:=Round(y*(1-(z+Origin.z)/SEEFAR))+Origin.Y;
end;
procedure TCanvas3D.SetBrush(const Value: TBrush);
begin
FCanvas2D.Brush:=Value;
end;procedure TCanvas3D.SetFCanvas2D(const Value: TCanvas);
begin
FFCanvas2D := Value;
end;procedure TCanvas3D.SetOrigin(const Value: T3DPoint);
begin
FOrigin := Value;
end;procedure TCanvas3D.SetPen(const Value: TPen);
begin
FCanvas2D.Pen:=Value;
end;procedure TCanvas3D.SetPixels(x, y, z: Integer; const Value: TColor);
begin
with Point3DTo2D(x,y,z) do
begin
FCanvas2D.Pixels[x,y]:=Value;
end;
end;procedure TCanvas3D.SetViewHeight(const Value: Integer);
begin
FViewHeight := Value;
end;procedure TCanvas3D.SetViewWidth(const Value: Integer);
begin
FViewWidth := Value;
end;
var
i:Integer;
Q:Double;procedure TCanvas3D.Sphere(x, y, z, r, hs, vs: Integer);
var
tx,ty,tz,hi:Integer;
hn,vn,ht,vt,tr:Double;
LastPoints:array of T2DPoint;
begin
hn:=RadianCount/(2*hs);
vn:=RadianCount/(2*vs);
SetLength(LastPoints,2*hs+1);
vt:=0;
while vt< RadianCount/2 do
begin
tz:=Round(FCosArray[Round(vt)]*r+z);
tr:=FSinArray[Round(vt)]*r;
ht:=0;
hi:=0;
tx:=Round(FCosArray[Round(ht)]*tr+x);
ty:=Round(FSinArray[Round(ht)]*tr+y);
with Point3DTo2D(tx,ty,tz) do
begin
FCanvas2D.MoveTo(x,y);
if vt>0 then
begin
FCanvas2D.LineTo(LastPoints[Round(hi)].x,LastPoints[Round(hi)].y);
FCanvas2D.MoveTo(x,y);
end;
LastPoints[Round(hi)].x:=x;
LastPoints[Round(hi)].y:=y;
Inc(hi);
end;
ht:=ht+hn;
while ht<=RadianCount do
begin
tx:=Round(FCosArray[Round(ht)]*tr+x);
ty:=Round(FSinArray[Round(ht)]*tr+y);
with Point3DTo2D(tx,ty,tz) do
begin
FCanvas2D.LineTo(x,y);
if vt>0 then
begin
FCanvas2D.LineTo(LastPoints[Round(hi)].x,LastPoints[Round(hi)].y);
FCanvas2D.MoveTo(x,y);
end;
LastPoints[Round(hi)].x:=x;
LastPoints[Round(hi)].y:=y;
Inc(hi);
end;
ht:=ht+hn;
end;
vt:=vt+vn;
end;
end;initialization
//---------------------------
FRadianStep:=2*PI/RadianCount;
Q:=0;
for i:=Low(FCosArray) to High(FCosArray) do
begin
FCosArray[i]:=Cos(Q);
FSinArray[i]:=Sin(Q);
Q:=Q+FRadianStep;
end;end.
//以下是一个测试单元
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls, QQCanvas3D, ExtDlgs, jpeg;
type TForm1 = class(TForm)
PaintBox1: TPaintBox;
PaintBox2: TPaintBox;
LoadPicBtn: TButton;
OPD1: TOpenPictureDialog;
ConverBtn: TButton;
procedure FormCreate(Sender: TObject);
procedure LoadPicBtnClick(Sender: TObject);
procedure ConverBtnClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
Ca3D:TCanvas3D; end;var
Form1: TForm1;implementation{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
Ca3D:=TCanvas3D.Create(PaintBox2.Canvas);
Ca3D.ViewWidth:=PaintBox2.Width;
Ca3D.ViewHeight:=PaintBox2.Height;
end;procedure TForm1.LoadPicBtnClick(Sender: TObject);
var
Pic:TPicture;
begin
if OPD1.Execute then
begin
Pic:=TPicture.Create;
Pic.LoadFromFile(OPD1.FileName);
PaintBox1.Canvas.StretchDraw(PaintBox1.ClientRect,Pic.Graphic);
Pic.Free;
end;
end;procedure TForm1.ConverBtnClick(Sender: TObject);
var
x,y,z:Integer;
begin
with PaintBox1,Canvas do
for y:=0 to Height-1 do
begin
z:=0;
for x:=0 to Width-1 do
begin
Ca3D.Pixels[x,y,z]:=Pixels[x,y];
inc(z,5);
end;
end;
end;end.
代码...应该不超过50行。
由图像中任意一点(x,y)计算出相对于视点O(x0,y0,z0)的三维坐标A(X,Y,Z),将图像中假想和屏幕相交的面作交平面(z=0),计算OA和交平面的点A'(x',y',z'=0)。根据(x',y')取整后的位置累加,叠加(注意多点重复叠加时颜色敏感度的权)平均值作为最终颜色。
每一个点算过来,计算量很大,我见过有人用汇编写,效果好一些,其实现在大部分这种工作都交给图形卡了,还是用opengl吧,呵呵
procedure TForm1.TiltBitmap(const InBitmap, OutBitmap: TBitmap;
const WidthTop, WidthBottom: integer);
const
clBackColor = clBlack;
BestQuality = True;
var
y, xWidthDiff, xWidthCurrentLine: Integer;
d: Real;
begin
OutBitmap.PixelFormat := InBitmap.PixelFormat;
if WidthTop > WidthBottom then
OutBitmap.Width := WidthTop
else
OutBitmap.Width := WidthBottom;
OutBitmap.Height := InBitmap.Height;
OutBitmap.Canvas.Brush.Color := clblack;
OutBitmap.Canvas.FillRect(OutBitmap.Canvas.ClipRect);
OutBitmap.Canvas.CopyMode := cmSrcCopy;
if BestQuality then
begin
{slower but better quality with color images}
SetStretchBltMode(OutBitmap.Canvas.Handle, HALFTONE);
SetBrushOrgEx(OutBitmap.Canvas.Handle, 0, 0, nil);
end
else
{quicker but slightly lower quality}
SetStretchBltMode(OutBitmap.Canvas.Handle, HALFTONE);
OutBitmap.Canvas.CopyMode := cmSrcCopy;
d := (WidthBottom - WidthTop) / OutBitmap.Height; for y := 0 to OutBitmap.Height - 1 do
begin
xWidthCurrentLine := Trunc(WidthTop + d * y);
xWidthDiff := (OutBitmap.Width - xWidthCurrentLine) div 2;
OutBitmap.Canvas.CopyRect(Rect(xWidthDiff, y, xWidthDiff +
xWidthCurrentLine, y + 1),
InBitmap.Canvas, Rect(0, y, InBitmap.Width, y + 1));
end;
end;
var
InBitmap, outbitmap: Tbitmap;
begin
if Image1.Picture.Bitmap.Empty then
begin
ShowMessage('请加载图片');
exit;
end
else
InBitmap := TBitmap.Create;
outbitmap := TBitmap.Create;
InBitmap.Assign(image1.Picture.Bitmap);
TiltBitmap(InBitmap, OutBitmap, 300, 600);
image1.Picture.Bitmap.Assign(outbitmap);
image1.Invalidate;
InBitmap.Free;
outbitmap.Free;
http://topic.csdn.net/t/20020719/11/886049.html
其中讨论的问题是你的逆问题:如何从非矩型投影转换为矩形,
但二者的原理是一样的,作的都是投影变换.2.要解决文字锯齿状,要研究反锯齿算法.
反锯齿算法任何计算机图形学书中都要讲到.在网上也很多,例如,可参考:
http://topic.csdn.net/t/20040114/13/2662782.html3.严格讲,图像经过转动,原来的一个象素,一般都不会
恰好变到新图像矩阵中的一个象素,而总会有一部分落到
它四周的象素方格中.反过来说,新图像中的每一个象素,必定
是原来图像几个像素共同变换得来的. 你要考虑每一个新图像
象素如何“反锯齿”问题。
为了较精确地绘制你的新图像,你要考虑的,就是如何找到
变换成每一个新图像象素的原图像象素,并按它们在新象素中所
占比例的大小,来进行加权平均.
另外哪位能搞到 印刷体仿宋字体,非正常仿宋体,如有字库能否发给我,谢谢 [email protected]
达到这副图片的效果也是可以的,要求完整算法,可以给500分都可以