在主程序中,演示了读取一个位图文件 1.bmp 并进行左右镜像以后,写入新的 BMP 文件 2.bmp
原始图像:


左右镜像后:

Module fcBMP24Mod
use , INTRINSIC :: ISO_C_Binding
Implicit None
Private
Integer(Kind=C_SHORT) , parameter :: BMP_FLAG = 19778 !"BM"
Integer , parameter , public :: KINDBMP = C_INT8_T
!DEC$ PACK:2
Type , public , Bind(C) :: BITMAPFILEHEADER
Integer(Kind=C_SHORT) :: cfType !//BM
Integer(Kind=C_INT) :: bfSize
Integer(Kind=C_SHORT) :: bfReserved1
Integer(Kind=C_SHORT) :: bfReserved2
Integer(Kind=C_INT) :: bfOffBits
End Type BITMAPFILEHEADER
Type , public , Bind(C) :: BITMAPINFOHEADER
Integer(Kind=C_INT) :: biSize
Integer(Kind=C_INT) :: biWidth
Integer(Kind=C_INT) :: biHeight
Integer(Kind=C_SHORT) :: biPlanes
Integer(Kind=C_SHORT) :: biBitCount
Integer(Kind=C_INT) :: biCompression
Integer(Kind=C_INT) :: biSizeImage
Integer(Kind=C_INT) :: biXPelsPerMeter
Integer(Kind=C_INT) :: biYPelsPerMeter
Integer(Kind=C_INT) :: biClrUsed
Integer(Kind=C_INT) :: biClrImportant
End Type BITMAPINFOHEADER
!DEC$ PACK
Type , public :: fcBMP24
Integer :: fUnit = 0
Type( BITMAPFILEHEADER ) :: FileHeader
Type( BITMAPINFOHEADER ) :: BmpHeader
contains
Procedure :: OpenBMP
Procedure :: ReadBMP
Procedure :: WriteBMP
Procedure :: CloseBMP
End Type
contains
Logical Function OpenBMP( this , cFile , Width , Height )
Class( fcBMP24 ) :: this
Character(len=*) :: cFile
Integer , optional :: Width , Height
integer :: k , u
OpenBMP = .false.
Open( NewUnit = u , File = cFile , access="stream" , ioStat = k , form="unformatted" )
If ( k /= 0 ) Return
If ( present( Width ) ) then
Read( u ) this % FileHeader
If ( this % FileHeader % cfType /= BMP_FLAG ) Return
Read( u ) this % BmpHeader
If ( this % BmpHeader % biBitCount /= 24 ) Return
If ( present( Width ) ) Width = this % BmpHeader % biWidth
If ( present( Height ) ) Height = this % BmpHeader % biHeight
End If
this%fUnit = u
OpenBMP = .true.
End Function OpenBMP
Logical Function ReadBMP( this , iData )
Class( fcBMP24 ) :: this
Integer(Kind=KINDBMP) :: iData(:,:,:)
integer :: i , nScanLine
ReadBMP = .false.
If ( this % fUnit == 0 ) return
If ( size(iData,dim=1) /= 3 ) return
If ( size(iData,dim=2) /= this % BmpHeader % biWidth ) return
If ( size(iData,dim=3) /= this % BmpHeader % biHeight ) return
nScanLine = 4 * ceiling( 3.0 * this % BmpHeader % biWidth / 4.0 )
Do i = 1 , this % BmpHeader % biHeight
Read( this % fUnit , Pos = this % FileHeader % bfOffBits + (i-1)*nScanLine +1 ) iData( : , : , i )
End Do
ReadBMP = .true.
End Function ReadBMP
Logical Function WriteBMP( this , iData )
Class( fcBMP24 ) :: this
Integer(Kind=KINDBMP) :: iData(:,:,:)
integer :: i , nScanLine
WriteBMP = .false.
If ( this % fUnit == 0 ) return
this % BmpHeader % biWidth = size(iData,dim=2)
this % BmpHeader % biHeight= size(iData,dim=3)
nScanLine = 4 * ceiling( 3.0 * this % BmpHeader % biWidth / 4.0 )
If ( size(iData,dim=1) /= 3 ) return
this % FileHeader % cfType = BMP_FLAG
this % FileHeader % bfSize = 54 + this % BmpHeader % biHeight * nScanLine
this % FileHeader % bfReserved1 = 0
this % FileHeader % bfReserved2 = 0
this % FileHeader % bfOffBits = 54
this % BmpHeader % biSize = 40
this % BmpHeader % biPlanes = 1
this % BmpHeader % biBitCount = 24
this % BmpHeader % biCompression = 0
this % BmpHeader % biSizeImage = 0
this % BmpHeader % biXPelsPerMeter = 3780
this % BmpHeader % biYPelsPerMeter = 3780
this % BmpHeader % biClrUsed = 0
this % BmpHeader % biClrImportant = 0
write( this % fUnit ) this % FileHeader
write( this % fUnit ) this % BmpHeader
Do i = 1 , this % BmpHeader % biHeight
Write( this % fUnit , Pos = 54 + (i-1)*nScanLine +1 ) iData( : , : , i )
End Do
If ( mod( this % BmpHeader % biWidth , 4_C_INT ) /= 0 ) &
write( this % fUnit , Pos = 54 + this % BmpHeader % biHeight * nScanLine ) 0_KINDBMP
WriteBMP = .true.
End Function WriteBMP
Subroutine CloseBMP( this )
Class( fcBMP24 ) :: this
If ( this % fUnit /= 0 ) Close( this%fUnit )
End Subroutine CloseBMP
End Module fcBMP24Mod
Program www_fcode_cn
Use fcBMP24Mod
Type( fcBMP24 ) :: myBmp , outBmp
Logical :: b
Integer( KINDBMP ) , allocatable :: D(:,:,:)
integer :: w , h , i , j
b = myBmp % OpenBMP( "1.bmp" , w , h )
write(*,*) "Size:" , w, h
allocate( D( 3 , w , h ) )
b = myBmp % ReadBMP( D )
Open( 13 , File = "color.txt" )
write( 13 , '(a)' ) "Blue Green Red"
Do i = 1 , h
Do j = 1 , w
write( 13 , '(3(i4,1x))' ) D(:,j,i)
End Do
End Do
b = outBmp % OpenBMP( "2.bmp" )
b = outBmp % WriteBmp( D( : , w:1:-1 , : ) )
call myBmp % CloseBMP()
call outBmp % CloseBMP()
End Program www_fcode_cn



