关于JPG图片旋转问题,急急急!!!



------
我想用VB将JPG图片旋转90度
在网上找了好多源代码,一般都是放在PICBOX上转成BMP,思路如下:
JPG->BMP->旋转90度->BMP->JPG
不过这样速度太慢了,因为我的JPG原图一般都是6M左右.一般转一个都需要好几分钟
请问各位有没有更好的方法,速度越快越好!
另,我要的是VB源代码,不要老告诉我用第三方软件什么去手动转.
还有,如果机子装了ACDsee,至需要在图片右键选择旋转多少度就可以了,速度也非常快!
,我听说可以引用ACDSee的控件什么,具体怎么做呢?



------
在 windows中,彩色图像在内存中一般都是按RGB(RGBA)格式存放的,也就是说不管你的原始图像在物理文件上是啥格式,要显示出来都要转换到这种格式。
------
6M的JPG图片,也够大啊!
我猜测你是不是要把数码相机里面倒置的图片摆正?如果是这样,没必要编程,用ACDSee选择多张倒置的图片,可以一次摆正。
------
引用 2 楼 chenjl1031 的回复:
6M的JPG图片,也够大啊!
我猜测你是不是要把数码相机里面倒置的图片摆正?如果是这样,没必要编程,用ACDSee选择多张倒置的图片,可以一次摆正。

------
引用 1 楼 laviewpbt 的回复:
在 windows中,彩色图像在内存中一般都是按RGB(RGBA)格式存放的,也就是说不管你的原始图像在物理文件上是啥格式,要显示出来都要转换到这种格式。

------
我知道你不需要显示出来,但是你总要把图像加载到内存后才能处理啊,也就是WINDOWS不能直接识别以JPG格式压缩后的图像数据,要对图像进行处理,必须先把图像转换RGB格式,才能处理,也就是说你6MB大小的图像,加载到内存后可能需要占用45MB左右的内存(这个要看你的JPG的压缩比)。 

如果我告诉你在我的破机器上,旋转5000*4000大小的JPG需要5秒时间 (就是给我一个图像到保存旋转后的图像所需时间)你满意不?
------
引用 5 楼 laviewpbt 的回复:
我知道你不需要显示出来,但是你总要把图像加载到内存后才能处理啊,也就是WINDOWS不能直接识别以JPG格式压缩后的图像数据,要对图像进行处理,必须先把图像转换RGB格式,才能处理,也就是说你6MB大小的图像,加载到内存后可能需要占用45MB左右的内存(这个要看你的JPG的压缩比)。

如果我告诉你在我的破机器上,旋转5000*4000大小的JPG需要5秒时间 (就是给我一个图像到保存旋转后的图像所需时间)你满意不?

------
引用 5 楼 laviewpbt 的回复:
我知道你不需要显示出来,但是你总要把图像加载到内存后才能处理啊,也就是WINDOWS不能直接识别以JPG格式压缩后的图像数据,要对图像进行处理,必须先把图像转换RGB格式,才能处理,也就是说你6MB大小的图像,加载到内存后可能需要占用45MB左右的内存(这个要看你的JPG的压缩比)。

如果我告诉你在我的破机器上,旋转5000*4000大小的JPG需要5秒时间 (就是给我一个图像到保存旋转后的图像所需时间)你满意不?

------
引用 7 楼 windfeel2008 的回复:
引用 5 楼 laviewpbt 的回复:
我知道你不需要显示出来,但是你总要把图像加载到内存后才能处理啊,也就是WINDOWS不能直接识别以JPG格式压缩后的图像数据,要对图像进行处理,必须先把图像转换RGB格式,才能处理,也就是说你6MB大小的图像,加载到内存后可能需要占用45MB左右的内存(这个要看你的JPG的压缩比)。

如果我告诉你在我的破机器上,旋转5000*4000大小的JPG需要5秒时间 (就是给我一个图像到保存旋转后的图像所需时…

------
用微软的图像查看器即可
------
laviewpbt厉害啊
------
路过。。。
------
路过 vb太难了

------
利用VC写个DLL,在VB里调用.
------
路过 牛人真多
------
路过
------
mark

------
gdi+ 相当简单
 Image img = Image.FromFile("your.jpg");
  Image imgdest = new Bitmap(img.Height, img.Width);
  Graphics g = Graphics.FromImage(imgdest);
  g.RotateTransform(90.0F);
  g.DrawImage(img,0, -1*img.Height);
  imgdest.Save("new.jpg",System.Drawing.Imaging.ImageFormat.Jpeg);  
这是c#的,如果嫌效率不高可以通过c++直接使用gdiplus 编非托管的
------
VB6么..
LZ用GDI+的Flat API吧...
vb.net可以直接用GDI+了.
PS:GDI+ Flat API就是8L贴的东东.
不是很复杂.不过声明API和结构很麻烦囧.
------
路过。这个问题不是难题吧。
------
好多牛人啊!!呵呵。。
------
Mark!
------

------
旋转一下这么麻烦呀,太强了。
------
引用 20 楼 ChrisAK 的回复:
VB6么..
LZ用GDI+的Flat API吧...
vb.net可以直接用GDI+了.
PS:GDI+ Flat API就是8L贴的东东.
不是很复杂.不过声明API和结构很麻烦囧.

------
JPG图片旋转90度
'以下代码在bas#############
Private Type POINTAPI
X As Long
y As Long
End Type

Private Type Bitmap
bmType As Long
bmWidth As Long
bmHeight As Long
bmWidthBytes As Long
bmPlanes As Integer
bmBitsPixel As Integer
BmBits As Long
End Type
Private Declare Function GetObject Lib "gdi32" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As Long
Private Declare Function GetTickCount Lib "kernel32" () As Long
Private Declare Function SelectObject Lib "gdi32" (ByVal hDC As Long, ByVal hObject As Long) As Long
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hDC As Long) As Long
Private Declare Function CreateCompatibleBitmap Lib "gdi32" (ByVal hDC As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long
Private Declare Function DeleteDC Lib "gdi32" (ByVal hDC As Long) As Long
Private Declare Function ReleaseDC Lib "user32" (ByVal hWnd As Long, ByVal hDC As Long) As Long
Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal X As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
Private Declare Function PlgBlt Lib "gdi32" (ByVal hdcDest As Long, lpPoint As POINTAPI, ByVal hdcSrc As Long, ByVal nXSrc As Long, ByVal nYSrc As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hbmMask As Long, ByVal xMask As Long, ByVal yMask As Long) As Long

Public Sub Rotate90(Pic As PictureBox)
Dim DefPoints(3) As POINTAPI
Dim MemDC As Long
Dim BHandle As Long
Dim OldObject As Long
Dim picINFO As Bitmap
Dim Width As Long, Height As Long, Temp As Long
Pic.AutoSize = True: Pic.AutoRedraw = True
GetObject Pic.Image, Len(picINFO), picINFO
Width = picINFO.bmWidth
Height = picINFO.bmHeight
MemDC = CreateCompatibleDC(Pic.hDC)
BHandle = CreateCompatibleBitmap(Pic.hDC, Width, Height)
OldObject = SelectObject(MemDC, BHandle)
BitBlt MemDC, 0, 0, Width, Height, Pic.hDC, 0, 0, vbSrcCopy
DefPoints(0).X = 0
DefPoints(0).y = Width
DefPoints(1).X = 0
DefPoints(1).y = 0
DefPoints(2).X = Height
DefPoints(2).y = Width
Pic.Move Pic.Left, Pic.Top, Pic.Height, Pic.Width
Set Pic.Picture = Nothing
PlgBlt Pic.hDC, DefPoints(0), MemDC, 0, 0, Width, Height, 0, 0, 0
SelectObject MemDC, OldObject
DeleteDC MemDC
DeleteObject BHandle
End Sub

'窗体代码#############
Private Sub Command1_Click()'旋转JPG图片90度
Dim t As Long
t = GetTickCount
Rotate90 Picture1
End Sub
Private Sub Command2_Click()'打开JPG图片
CommonDialog1.Filter = " *.jpg |*.jpg"
  CommonDialog1.ShowOpen
  If CommonDialog1.Filename <> "" Then
  Picture1.Picture = LoadPicture(CommonDialog1.Filename)
End Sub


------
c++ 注意的是
一个要在使用gdi+之前调用gdiplusstartup
之后要gdiplusshutdown
图像格式不像托管的那样直接拿来就用

  CLSID jpgClsid;
  GetEncoderClsid(L"image/jpeg", &jpgClsid);
  CLSID pngClsid;
  GetEncoderClsid(L"image/png", &pngClsid);
   

------
用c#写6行代码,c++估计在12行左右
------

实际上,有两种选择:

1 利用 PictureBox 加载图片,获取像素后做旋转运算,然后可以直接保存为 .jpg 文件(不需要 .bmp 过度)。这样做的好处是,不必解析 .jpg 文件结构。

2 直接解析 .jpg 文件,取得像素,运算,结构成新的 .jpg 文件,写文件。这个需要熟悉 .jpg 的文件结构。
------
不用转化为RGB。
JPG是压缩的YCbCr的数据,把JPG解码为YCbCr,然后旋转YCbCr,再编码为JPG,省去转化为RGB的时间,应该会快点。
------
菜鸟来看看,呵呵
------
http://www.92dotnet.com/index.aspx
------
路过
------
路过
------
好复杂啊
------
看看!
------
我晕啊!!!以为自己可以了的。。。。人外有人啊
------
我晕
------
如果旋转的是90,180,270的话,应该不需要转换。我觉得JPG文件中,应该有方向的选项。

你可以自己试一下,把一个JPG文件用Windows来打开,下面有一个旋转按钮,可以以90度进行旋转,速度飞快。

你可以试一下,在转换前,与转换后,比较一下JPG文件究竟哪些内容发生了变化。
------
我刚才试过,好象不行的,还是得编程。呵呵!
------
我也想知道
------
ding yixia //
------
打酱油 ,
 看到好多牛人 
 VB 有点犯晕 ,对于新入行的程序员来讲 VB是个大问题!!!
------
楼上的都搞错了,LZ问的是JPG旋转90度,这种特殊情况下不需要把JPG解压为BMP来处理,ACDSee是直接对JPG的数据来处理的,这种方法速度要快一个数量级,而且不会损失画质


------
路过
------
引用 45 楼 psic__ 的回复:
楼上的都搞错了,LZ问的是JPG旋转90度,这种特殊情况下不需要把JPG解压为BMP来处理,ACDSee是直接对JPG的数据来处理的,这种方法速度要快一个数量级,而且不会损失画质

------
学习
------
jf
------
ding
------
路过!
------
引用 19 楼 hdt 的回复:
gdi+ 相当简单
Image img = Image.FromFile("your.jpg");
Image imgdest = new Bitmap(img.Height, img.Width);
Graphics g = Graphics.FromImage(imgdest);
g.RotateTransform(90.0F);
g.DrawImage(img,0, -1*img.Height);
imgdest.Save("new.jpg",System.Drawing.Imaging.ImageFormat.Jpeg);
这是c#的,如果嫌效率不高可以通过c++直接使用gdiplus 编非托管的

------
我没有什么好的建议,不好意思!
------
mark
------
study
------
如果只是修改文件的话,修改exif信息就好了,别的不用动。
具体是tiff ifd0的orientation域,改两个字节就行,详见exif标准
------
有这种插件吗??直接用PS吧
------
这个我不在行,呵呵
------
高手真是多 顶
------
用GDI+ 矩阵旋转 效率超级高
------
看不懂啊
------


img.RotateFlip(RotateFlipType.Rotate90FlipNone);

------
ddddddddddddddddddddddddddddddddddddddddd
------
写得很好
------
很好
------
有点难度。
------
牛B人物
------
帮顶啊!这个比较麻烦 ,!
------
我下载的旋转图片的源代码旋转图片也用时不多,但是在将BMP保存为JPG的时候太慢了
------
用格式工厂,就可以转了呀
------
用微软的图像查看器即可
------
不会 我
------
争分
------
帮顶
------
学习学习
------
不懂,感觉写了一大堆程序,还不如直接用ACD see转好放进去好了
------
我也想学习学习!
------
不能用GDI+吗= =
------
用画图不就能翻转么
------
要求不高的话把图片分辨率设小点,应该会快点啊
------
建议你将其引入ps中把像素改小点在进行处理
------
如果方便的话把图像发给我,我帮你改
------
目前搞不懂,不过顶一下
------
为什么不缩小再旋转呢?
------

------
`````````````````````````````````````````````````````````````````
------
在 windows中,彩色图像在内存中一般都是按RGB(RGBA)格式存放的,也就是说不管你的原始图像在物理文件上是啥格式,要显示出来都要转换到这种格式。
------
支持一楼的
------
直接用图片查看器不就搞定了,就是慢点,谁叫你用那么好的相机,还不摆正~~~
------
不懂图像处理,顶贴学习...
------
我要下资料
------
DING
------
erfgedfdsfsd
------
6M的JPG图片,够大
------
问题好像没有得到根本解决,不过看后也学到些东西。。
就看懂个用GDI的方式。。
------
看不懂,啥玩意
桂ICP备07017180号