用Fortran保存PPM
因此,作为学习Fortran的练习,我决定重新实现并行编程类中的一项任务,其目的是加载、水平模糊,然后保存PPM(P3)图像文件。我的作品是为了阅读(它有适当的深度和尺寸),但当我去保存数据时,图像出现了混乱,几乎一半的数据丢失用Fortran保存PPM,fortran,Fortran,因此,作为学习Fortran的练习,我决定重新实现并行编程类中的一项任务,其目的是加载、水平模糊,然后保存PPM(P3)图像文件。我的作品是为了阅读(它有适当的深度和尺寸),但当我去保存数据时,图像出现了混乱,几乎一半的数据丢失 subroutine loadppm( this, filename ) class( ppmfile ) :: this character( len = * ), intent( in ) :: f
subroutine loadppm( this, filename )
class( ppmfile ) :: this
character( len = * ), intent( in ) :: filename
integer :: funit, cdepth, cwidth, cheight, x, y, cr, cg, cb, reason
character( 2 ) :: header
open( newunit = funit, file = filename, status = 'old', action = 'read', access = 'stream', form = 'formatted' )
read( funit, '(a2)' ) header
if ( header /= 'P3' ) then
print *, "Invalid file type detected."
stop
end if
read( funit, * ) cwidth, cheight
read( funit, * ) cdepth
if ( cdepth /= 255 ) then
print *, "Invalid colour depth detected."
stop
end if
this%width = cwidth
this%height = cheight
this%depth = cdepth
allocate( this%data( 3, this%width, this%height ) )
do y = 1, this%width
do x = 1, this%height
read( funit, *, IOSTAT = reason ) cr, cg, cb
if ( reason < 0 ) then
! EOF reached
exit
exit
end if
this%data( 1, y, x ) = cr
this%data( 2, y, x ) = cg
this%data( 3, y, x ) = cb
end do
end do
close( funit )
end subroutine loadppm
第一行是标题,第二行是尺寸,第三行是颜色深度(始终为255)。之后的所有行都是像素数据,每个三元组都是给定像素的RGB值。当我让它输出读入的内容时,第一个三元组是正确的(如中所示,它匹配文件中的内容),但之后的一切都是错误的;如中所示,它与文件中的内容不匹配。文件中的换行符被忽略,但任何给定值之间只有一个空格。Erik
您遇到的问题是如何使用read语句。在fortran语言中,read语句总是在完成后前进到下一行,即使该行上还有数据。这就是为什么一些数据被正确读取的原因,它是行开头的数据
如果PPM中的所有整数正好是3个字符,则可以使用advance='no'
解决此问题:
READ( funit, '(I3)', IOSTAT = reason, advance='no' ) cr
READ( funit, '(I3)', IOSTAT = reason, advance='no' ) cg
READ( funit, '(I3)', IOSTAT = reason, advance='no' ) cb
但对于更一般的情况,您需要将整行作为字符串读入,然后手动将其拆分到数组中 欢迎光临,请坐飞机。请把代码放在这里作为文本,不要只是链接它。这是非常重要的。如果太大,请缩小。使用有问题的方法进行修改,并删除调试信息。每隔读取一个像素就错了,错在哪里?假设你是一个去看医生的病人,你告诉医生我的腿不行了,然后医生会开始问一系列问题来找出你的腿有什么问题。现在,想象你是一个试图帮助一个noob的人,试着预测我们可能需要回答的所有问题。。。
READ( funit, '(I3)', IOSTAT = reason, advance='no' ) cr
READ( funit, '(I3)', IOSTAT = reason, advance='no' ) cg
READ( funit, '(I3)', IOSTAT = reason, advance='no' ) cb