将表数据旋转90度

 /*
将表数据旋转90度(2007-11-19于海南三亚)

将下表数据:
A                    b           c           d           e          
-------------------- ----------- ----------- ----------- -----------
x                    1           2           3           4
y                    5           6           7           8
z                    9           10          11          12

转化成如下结果:
a                    x          y          z         
-------------------- ---------- ---------- ----------
b                    1          5          9
c                    2          6          10
d                    3          7          11
e                    4          8          12

*/

--生成测试数据
create table test1(A varchar(20),b int,c int,d int,e int)
insert into test1 select 'x',1,2 ,3 ,4
insert into test1 select 'y',5,6 ,7 ,8
insert into test1 select 'z',9,10,11,12
go

--生成中间数据表
declare @s varchar(8000)
set @s = 'create table test2(a varchar(20)'
select @s = @s + ',' + A + ' varchar(10)' from test1
set @s = @s + ')'
exec(@s)
print @s
--借助中间表实现行列转换
declare @name varchar(20)

declare t_cursor cursor for
select name from syscolumns
where id=object_id('test1') and colid > 1 order by colid

open t_cursor

fetch next from t_cursor into @name

while @@fetch_status = 0
begin
   
exec('select ' + @name + ' as t into test3 from test1')
   
set @s='insert into test2 select ''' + @name + ''''
   
select @s = @s + ',''' + rtrim(t) + '''' from test3
   
exec(@s)
   
exec('drop table test3')
   
fetch next from t_cursor into @name
end
close t_cursor
deallocate t_cursor

--查看行列互换处理结果
select * from test1
select * from test2

--删除表
drop table test1
drop table test2
----------------------------------------------------------------------------
/*
固定的写法:*/
select t1.* , t2.y , t3.z from
(
select a = 'b' , x = b from test1 where a = 'x') t1,
(
select a = 'b' , y = b from test1 where a = 'y') t2,
(
select a = 'b' , z = b from test1 where a = 'z') t3
where t1.a = t2.a and t1.a = t2.a
union all
select t1.* , t2.y , t3.z from
(
select a = 'c' , x = c from test1 where a = 'x') t1,
(
select a = 'c' , y = c from test1 where a = 'y') t2,
(
select a = 'c' , z = c from test1 where a = 'z') t3
where t1.a = t2.a and t1.a = t2.a
union all
select t1.* , t2.y , t3.z from
(
select a = 'd' , x = d from test1 where a = 'x') t1,
(
select a = 'd' , y = d from test1 where a = 'y') t2,
(
select a = 'd' , z = d from test1 where a = 'z') t3
where t1.a = t2.a and t1.a = t2.a
union all
select t1.* , t2.y , t3.z from
(
select a = 'e' , x = e from test1 where a = 'x') t1,
(
select a = 'e' , y = e from test1 where a = 'y') t2,
(
select a = 'e' , z = e from test1 where a = 'z') t3
where t1.a = t2.a and t1.a = t2.a

----------------------------------------------------------------------------
/*

表tb,数据如下:
项目种类  业绩  提成
洗吹类  200   10
外卖      100   5
合计      300   15
转换成:
项目种类  洗吹类  外卖  合计
业绩      200     100   300
提成      10      5     15
*/

create table tb
(
  项目种类
varchar(10),
  业绩    
int,
  提成    
int
)

insert into tb(项目种类,业绩,提成) values('洗吹类',200,10)
insert into tb(项目种类,业绩,提成) values('外卖'  ,100,5)
insert into tb(项目种类,业绩,提成) values('合计'  ,300,15)
go

select 项目种类,sum(洗吹类) as 洗吹类 , sum(外卖) as 外卖 , sum(合计) as 合计 from
(
 
select 项目种类 = '业绩',
         洗吹类  
= case when 项目种类 = '洗吹类' then 业绩 else 0 end,
         外卖    
= case when 项目种类 = '外卖'   then 业绩 else 0 end,
         合计    
= case when 项目种类 = '合计'   then 业绩 else 0 end
 
from tb
union all
 
select 项目种类 = '提成' ,
         洗吹类  
= case when 项目种类 = '洗吹类' then 提成 else 0 end,
         外卖    
= case when 项目种类 = '外卖'   then 提成 else 0 end,
         合计    
= case when 项目种类 = '合计'   then 提成 else 0 end
 
from tb
) m
group by 项目种类
order by 项目种类 desc

drop table tb

/*
项目种类 洗吹类      外卖        合计         
-------- ----------- ----------- -----------
业绩     200         100         300
提成     10          5           15

(所影响的行数为 2 行)
*/

--------------------------------------------------------------------------
/*

数据库中tb表格如下

月份    工资   福利  奖金
1月     100    200   300
2月     110    210   310
3月     120    220   320
4月     130    230   330

我想得到的结果是

项目   1月    2月  3月  4月
工资   100    110  120  130
福利   200    210  220  230
奖金   300    310  320  330

就是说完全把表格的行列颠倒,有点像那种旋转矩阵,请问如何用sql 语句实现?
*/

if exists (select * from dbo.sysobjects
where id = object_id(N'[dbo].[p_zj]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[p_zj]
GO
/*--行列互换的通用存储过程(原著:邹建):将指定的表,按指定的字段进行行列互换*/

create proc p_zj
      
@tbname sysname, --要处理的表名
       @fdname sysname, --做为转换的列名
       @new_fdname sysname='' --为转换后的列指定列名
as
declare @s1 varchar(8000) , @s2 varchar(8000),
       
@s3 varchar(8000) , @s4 varchar(8000),
       
@s5 varchar(8000) , @i varchar(10)
select @s1 = '' , @s2 = '' , @s3 = '' , @s4 = '' , @s5 = '' , @i = '0'
select @s1 = @s1 + ',@' + @i + ' varchar(8000)',
      
@s2 = @s2 + ',@' + @i + '=''' + case isnull(@new_fdname , '') when '' then ''
      
else @new_fdname + '=' end + '''''' + name + '''''''',
      
@s3 = @s3 + 'select @' + @i + '=@' + @i + '+'',['' + [' + @fdname +
      
']+'']=''+cast([' + name + '] as varchar) from [' + @tbname + ']',
      
@s4 = @s4 + ',@' + @i + '=''select ''+@' + @i,
      
@s5 = @s5 + '+'' union all ''+@' + @i,
      
@i=cast(@i as int)+1
from syscolumns
where object_id(@tbname)=id and name<>@fdname

select @s1=substring(@s1,2,8000),
      
@s2=substring(@s2,2,8000),
      
@s4=substring(@s4,2,8000),
      
@s5=substring(@s5,16,8000)
exec('declare ' + @s1 + 'select ' + @s2 + @s3 + 'select ' + @s4 + '
exec(
' + @s5 + ')')
go

--用上面的存储过程测试:

create table Test(月份 varchar(4), 工资 int, 福利 int, 奖金 int)
insert Test
select '1月',100,200,300 union all
select '2月',110,210,310 union all
select '3月',120,220,320 union all
select '4月',130,230,330
go

exec p_zj 'Test', '月份' , '项目'

drop table Test
drop proc p_zj

/*
项目   1月         2月         3月         4月         
---- ----------- ----------- ----------- -----------
福利   200         210         220         230
工资   100         110         120         130
奖金   300         310         320         330

(所影响的行数为 3 行)
*/

/*
静态写法(SQL2005)
*/
--测试环境
create table Test(月份 varchar(4), 工资 int, 福利 int, 奖金 int)
insert Test
select '1月',100,200,300 union all
select '2月',110,210,310 union all
select '3月',120,220,320 union all
select '4月',130,230,330
go
--测试语句
SELECT * FROM
(
 
SELECT 考核月份,月份,金额 FROM
     (
SELECT 月份, 工资, 福利, 奖金 FROM Test) p
  UNPIVOT
     (金额
FOR 考核月份 IN (工资, 福利, 奖金))AS unpvt
) T
PIVOT
(
MAX(金额)  FOR 月份 in ([1月],[2月],[3月],[4月]))AS pt

--测试结果

/*
考核月份  1月     2月      3月     4月
-------  -----  -----   ------  -------
福利200210220230
工资100110120130
奖金300310320330
*/

--删除环境
Drop table Test

<think>好的,我需要帮助用户解决如何将通过`cat /dev/fb0`获取的framebuffer数据进行90旋转的问题。首先,我需要理解用户的需求以及现有的相关知识。 用户提到的引用[1]中提到了使用ffmpeg将原始数据转换为PNG图像,但用户希望直接对原始数据进行旋转处理,而不是转换后再旋转。引用[3]中的RGB565TO1555宏可能涉及像素格式转换,这可能与处理原始数据时的像素格式有关。 首先,framebuffer的数据结构是怎样的呢?通常,framebuffer的像素排列是线性的,按行存储,每个像素的格式可能不同,比如RGB565、RGB24等。用户需要旋转90,这涉及到将原始的行列转置,并且可能调整每个像素的位置。 步骤一:确定framebuffer的参数。用户需要知道屏幕的分辨率(如宽W和高H)、每个像素的位深(如bpp)、像素格式(如RGB排列顺序)。这些信息可以通过`fbset`命令或直接读取`/sys/class/graphics/fb0`下的文件获取。 步骤二:读取原始数据。使用`cat /dev/fb0 > frame.raw`获取原始数据,但需要注意权限问题,可能需要sudo。 步骤三:旋转算法。旋转90意味着将原来的第i行变为旋转后的第(H-1-i)列。例如,原始坐标(x,y)旋转后变为(y, W-1-x)。对于每个像素,需要重新计算其在新缓冲区中的位置。需要注意的是,旋转后的分辨率会变为H x W,所以旋转后的图像宽和高会交换。 步骤四:处理像素格式。如果像素格式是RGB24(每个像素3字节),那么每个像素需要整体移动。如果是RGB565(每个像素2字节),同样需要按像素处理。可能需要根据具体的像素格式调整读取和写入的方式。 步骤五:实现方法。可以用C、Python等语言编写程序,读取原始数据,按旋转后的坐标写入新缓冲区,然后输出旋转后的数据。或者使用图像处理库如ImageMagick或ffmpeg,但用户可能希望直接处理原始数据,所以手动实现更合适。 潜在问题:像素格式的解析是否正确,旋转后的数据是否正确对齐,以及性能问题,特别是当分辨率较高时,处理时间可能较长。另外,如果framebuffer使用了非标准的像素格式,可能需要特别处理。 测试步骤:用户可以先获取一个小分辨率的framebuffer数据,进行旋转处理,然后使用ffmpeg转换为图像查看效果,验证旋转是否正确。例如,使用ffmpeg命令时指定旋转后的宽和高,并确保像素格式正确。 引用[3]中的宏可能用于像素格式转换,如果在旋转过程中需要改变像素格式(比如从RGB565转RGB555),可能需要类似的处理。但旋转本身不涉及格式转换,只是像素位置的调整。 总结,解决方案的大致步骤是:获取framebuffer参数,读取原始数据,按旋转逻辑重新排列像素,输出旋转后的数据。需要特别注意像素格式和分辨率的变化。</think>### 通过旋转framebuffer数据的实现步骤 #### 1. 获取framebuffer参数 首先需确认屏幕分辨率($W \times H$)、像素格式(如RGB24、RGB565)和位深(如24bpp、16bpp)。可通过以下命令获取: ```bash fbset # 或查看系统文件 cat /sys/class/graphics/fb0/virtual_size cat /sys/class/graphics/fb0/bits_per_pixel ``` #### 2. 解析原始数据格式 假设像素格式为RGB24(每个像素占3字节),则原始数据排列为: $$ \text{原始数据}=[P_{0,0}, P_{1,0}, \dots, P_{W-1,0}, P_{0,1}, \dots, P_{W-1,H-1}] $$ 其中$P_{x,y}$示坐标$(x,y)$的像素值。 #### 3. 旋转算法原理 旋转90后,新坐标$(x',y')$与原坐标$(x,y)$的关系为: $$ x' = y \\ y' = W - 1 - x $$ 旋转后的数据尺寸变为$H \times W$,需按新尺寸重新排列像素。 #### 4. 代码实现(Python示例) ```python import numpy as np # 参数设置 width = 320 # 原宽W height = 240 # 原高H bpp = 3 # 每像素字节数(RGB24为3字节) # 读取原始数据 with open("frame.raw", "rb") as f: raw_data = f.read() # 转换为numpy数组并重塑形状 arr = np.frombuffer(raw_data, dtype=np.uint8).reshape((height, width, bpp)) # 旋转90 rotated_arr = np.rot90(arr, k=1, axes=(1,0)) # axes参数控制旋转方向 # 保存旋转数据 with open("rotated.raw", "wb") as f: f.write(rotated_arr.tobytes()) ``` #### 5. 使用FFmpeg验证结果 将旋转后的数据转换为图像验证: ```bash ffmpeg -vcodec rawvideo -f rawvideo -pix_fmt rgb24 -s 240x320 -i rotated.raw -vcodec png rotated.png ``` 需注意旋转后的尺寸为$H \times W$(如240x320→320x240变为240x320的旋转后尺寸)。 ### 关键注意事项 1. **像素格式对齐**:若实际像素格式非RGB24(如RGB565),需调整代码中的`bpp`和reshape逻辑[^3]。 2. **方向控制**:`np.rot90`的`k`参数控制旋转次数(k=1为90,k=3为270)。 3. **性能优化**:大分辨率数据可能需分块处理或使用GPU加速。 ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值