![]() |
#2
sam_jiang2023-02-26 13:05
|
不管怎样先把代码发上来,希望各位大侠帮忙分析一下原因。
二级化的代码是吹版提供的,在此表示鸣谢!

**************************************************
*-- Form: form1 (d:\documents\visual foxpro 项目\cpsb.scx)
*-- ParentClass: form
*-- BaseClass: form
*-- Time Stamp: 02/25/23 02:51:06 PM
*
DEFINE CLASS form1 AS form
Top = 0
Left = 0
Height = 716
Width = 984
DoCreate = .T.
Caption = "Form1"
FontSize = 12
Name = "Form1"
ADD OBJECT image1 AS image WITH ;
Picture = "原图.jpg", ;
Height = 50, ;
Left = 125, ;
Top = 42, ;
Width = 230, ;
Name = "Image1"
ADD OBJECT label1 AS label WITH ;
AutoSize = .T., ;
FontSize = 12, ;
Caption = "原图", ;
Height = 20, ;
Left = 225, ;
Top = 17, ;
Width = 34, ;
Name = "Label1"
ADD OBJECT image2 AS image WITH ;
Picture = "", ;
Height = 50, ;
Left = 549, ;
Top = 42, ;
Width = 230, ;
Name = "Image2"
ADD OBJECT image3 AS image WITH ;
Picture = "", ;
Height = 50, ;
Left = 125, ;
Top = 221, ;
Width = 230, ;
Name = "Image3"
ADD OBJECT image4 AS image WITH ;
Picture = "", ;
Height = 50, ;
Left = 550, ;
Top = 221, ;
Width = 230, ;
Name = "Image4"
ADD OBJECT command1 AS commandbutton WITH ;
AutoSize = .T., ;
Top = 15, ;
Left = 634, ;
Height = 25, ;
Width = 72, ;
Caption = "生成灰阶图", ;
Name = "Command1"
ADD OBJECT command2 AS commandbutton WITH ;
AutoSize = .T., ;
Top = 190, ;
Left = 210, ;
Height = 25, ;
Width = 72, ;
Caption = "生成黑白图", ;
Name = "Command2"
ADD OBJECT command3 AS commandbutton WITH ;
AutoSize = .F., ;
Top = 190, ;
Left = 629, ;
Height = 25, ;
Width = 84, ;
Caption = "框选文字范围", ;
Name = "Command3"
ADD OBJECT label2 AS label WITH ;
Caption = "Label2", ;
Height = 16, ;
Left = 530, ;
Top = 200, ;
Width = 38, ;
Name = "Label2"
ADD OBJECT label3 AS label WITH ;
Caption = "Label2", ;
Height = 16, ;
Left = 761, ;
Top = 272, ;
Width = 38, ;
Name = "Label3"
PROCEDURE command1.Click
huijie(thisform.image1.Picture,"灰阶.bmp")
thisform.image2.Picture="灰阶.bmp"
ENDPROC
PROCEDURE command2.Click
quzao1(thisform.image1.Picture,"黑白.bmp")
thisform.image3.Picture="黑白.bmp"
thisform.image4.Picture="黑白.bmp"
ENDPROC
PROCEDURE command3.Click
noldcolor=thisform.ForeColor
thisform.ForeColor=RGB(255,0,0)
cstr=FILETOSTR(thisform.image4.Picture) &&图像文件流
colordata=right(cstr,LEN(cstr)-54) &&提取图像像素数据
****将图像数据转换为一个长为image4.width,宽为image4.height的由0和1组成的矩阵********
colordata=STRTRAN(colordata,REPLICATE(CHR(0),3)+CHR(255),"1") &&将黑色像素转换为1
colordata=STRTRAN(colordata,REPLICATE(CHR(255),3)+CHR(255),"0") &&将白色像素转换为0
**********************************************************************************
LOCAL nposition,nleft,ntop,nright,nbottom,nx,ny,colordata1,x,y
nx=thisform.image4.Width
ny=thisform.image4.height
nposition=AT("1",colordata,1) &&定位第一个黑色像素的位置
ntop=INT(nposition/nx) &&确定第一个黑色像素所在行
nposition=rAT("1",colordata,1) &&定位倒数第一个黑色像素的位置
nbottom=CEILING(nposition/nx) &&确定最后一个黑色像素所在行
****************************************转换矩阵**********************************************
colordata1=""
FOR j=1 TO nx
FOR i=1 TO ny
colordata1=colordata1+SUBSTR(colordata,nx*(i-1)+j,1)
ENDFOR
ENDFOR
*********************得到一个翻转的像素矩阵,以确定最左侧的黑色像素位置**************************
nposition=AT("1",colordata1,1) &&定位第一个黑色像素的位置
nleft=INT(nposition/ny) &&确定第一个黑色像素所在行,即第一个矩阵所在的列
nposition=rAT("1",colordata1,1) &&定位第一个黑色像素的位置
nright=INT(nposition/ny) &&确定倒数第一个黑色像素所在行,即第一个矩阵所在的列
x=thisform.image4.Left
y=thisform.image4.Top
thisform.Box(x+nleft,y+ntop-1,x+nright+1,y+nbottom+1)
*!* WITH thisform.image4
*!* thisform.Line(.left,.top+9,.left+.width,.top+9)
*!* thisform.Line(.left,.top+39,.left+.width,.top+39)
*!* thisform.Line(.left+13,.top,.left+13,.top+.height)
*!* thisform.Line(.left+48,.top,.left+48,.top+.height)
*!* thisform.Line(.left+69,.top,.left+69,.top+.height)
*!* thisform.Line(.left+83,.top,.left+83,.top+.height)
*!* thisform.Line(.left+93,.top,.left+93,.top+.height)
*!* thisform.Line(.left+107,.top,.left+107,.top+.height)
*!* thisform.Line(.left+127,.top,.left+127,.top+.height)
*!* thisform.Line(.left+144,.top,.left+144,.top+.height)
*!* thisform.Line(.left+164,.top,.left+164,.top+.height)
*!* thisform.Line(.left+184,.top,.left+184,.top+.height)
*!* thisform.Line(.left+199,.top,.left+199,.top+.height)
*!* thisform.Line(.left+.width-10,.top,.left+.width-10,.top+.height)
*!* ENDWITH
thisform.ForeColor=noldcolor
ENDPROC
PROCEDURE label2.Init
this.AutoSize=.t.
this.Caption="("+TRANSFORM(thisform.image4.Left)+","+TRANSFORM(thisform.image4.Top)+")"
ENDPROC
PROCEDURE label3.Init
this.AutoSize=.t.
this.Caption="("+TRANSFORM(thisform.image4.Left+thisform.image4.width)+","+TRANSFORM(thisform.image4.Top+thisform.image4.height)+")"
ENDPROC
ENDDEFINE
*
*-- EndDefine: form1
**************************************************
二级化代码
quzao1.prg

PARAMETERS infile, outfile
IF PARAMETERS()=0
cDefPath = ADDBS(JUSTPATH(SYS(16)))
SET DEFAULT TO (cDefPath)
** 输入/输出文件
inFile = cDefPath + "test.png"
outFile = cDefPath + "test.bmp"
ENDIF
DECLARE long GdiplusStartup IN gdiplus long@,string@,long
DECLARE long GdiplusShutdown IN gdiplus long
DECLARE long GdipCreateBitmapFromScan0 IN gdiplus long,long,long,long,string@,long@
DECLARE long GdipGetImageGraphicsContext IN gdiplus long,long@
DECLARE long GdipLoadImageFromFile IN gdiplus string@,long@
DECLARE long GdipGetImageWidth IN gdiplus long,long@
DECLARE long GdipGetImageHeight IN gdiplus long,long@
DECLARE long GdipSaveImageToFile IN gdiplus long,string@,string@,long
DECLARE long GdipDrawImageRectI IN gdiplus long,long,long,long,long,long
DECLARE long GdipDisposeImage IN gdiplus long
DECLARE long GdipDeleteGraphics IN gdiplus long
DECLARE long GdipBitmapLockBits IN GDIPLUS long, string@, long, long, string@
DECLARE long GdipBitmapUnlockBits IN GDIPLUS long, string@
DECLARE long GdipCreateFromHDC IN gdiplus long,long@
DECLARE long GetDC IN user32 long
DECLARE long ReleaseDC IN user32 long,long
#define ImageLockModeReadWrite 0x0003
#define PixelFormat_32bppARGB 0x0026200A
** 初始化GDI
stGSI = 0h01000000000000000000000000000000
pGDI = 0
GdiplusStartup(@pGDI, @stGSI, 0)
** 载入文件
pImage = 0
GdipLoadImageFromFile(STRCONV(inFile+0h00,5), @pImage)
nWidth = 0
nHeight = 0
GdipGetImageWidth(pImage, @nWidth)
GdipGetImageHeight(pImage, @nHeight)
** 统一转换为32位ARGB格式
pBitmap = 0
GdipCreateBitmapFromScan0(nWidth, nHeight, 0, PixelFormat_32bppARGB, 0, @pBitmap)
pGraphics = 0
GdipGetImageGraphicsContext(pBitmap, @pGraphics)
GdipDrawImageRectI(pGraphics, pImage, 0, 0, nWidth, nHeight)
GdipDisposeImage(pImage)
** 获取缓存图像数据地址和大小
stRct = REPLICATE(0h00,8) + BINTOC(nWidth,"4rs") + BINTOC(nHeight,"4rs")
stBmpData = REPLICATE(0h00, 24) && BITMAPDATA 结构
GdipBitmapLockBits(pBitmap, @stRct, ImageLockModeReadWrite, PixelFormat_32bppARGB, @stBmpData)
pData = CTOBIN(SUBSTR(stBmpData,17,4),"4rs") && 图像数据首址
nCount = nWidth * nHeight * 4 && 图像数据字总节数(32位4字节)
** 转换图像数据
Gray(pData, nCount) && 灰度化
Binary(pData, nCount) && 二值化
GdipBitmapUnlockBits(pBitmap, @stBmpData) &&更新数据
** 输出文件
CLSID_BMP = 0h00F47C55041AD3119A730000F81EF32E
GdipSaveImageToFile(pBitmap, STRCONV(outFile+0h00,5), CLSID_BMP, 0)
GdipDeleteGraphics(pGraphics)
GdipDisposeImage(pBitmap)
** 显示图片
DrawImageWindowFromFile(_screen.hWnd, 10, 10, nWidth, nHeight, outFile)
GdiplusShutdown(pGDI)
*CLEAR ALL
RETURN
** 灰度化
FUNCTION Gray(pData, nCount)
FOR i=0 TO nCount-1 STEP 4
avg = 0.114 * ASC(SYS(2600,pData+i,1));
+ 0.587 * ASC(SYS(2600,pData+i+1,1));
+ 0.299 * ASC(SYS(2600,pData+i+2,1))
avg = INT(avg)
SYS(2600,pData+i,3,CHR(avg)+CHR(avg)+CHR(avg))
ENDFOR
ENDFUNC
** 二值化
FUNCTION Binary(pData, nCount)
* 计算阈值
k1 = 127 && 随机取0~255
k2 = 0
DO WHILE k1 != k2
k2 = k1
avgPix = 0
avgBac = 0
avgPixCnt = 0
FOR i=0 TO nCount-1 STEP 4
FOR j=i TO i+2 && R、G、B,不考虑A
ki = ASC(SYS(2600,pData+j,1))
IF ki < k2
avgPix = avgPix + ki && 像素数据
avgPixCnt = avgPixCnt + 1
ELSE
avgBac = avgBac + ki && 背景数据
ENDIF
ENDFOR
ENDFOR
avgPix = INT(avgPix / avgPixCnt)
avgBac = INT(avgBac / (nCount-avgPixCnt))
k1 = INT((avgPix+avgBac) / 2)
ENDDO
* 二值化
FOR i=0 TO nCount-1 STEP 4
FOR j=i TO i+2
ki = IIF(ASC(SYS(2600,pData+j,1)) < k1, 0, 255)
SYS(2600, pData+j, 1, CHR(ki))
ENDFOR
ENDFOR
ENDFUNC
** 显示图片
FUNCTION DrawImageWindowFromFile(hWnd, nX, nY, nWidth, nHeight, cFileName)
LOCAL hDC, pImage, pGraphics
pImage = 0
GdipLoadImageFromFile(STRCONV(cFileName+0h00,5), @pImage)
hDC = GetDC(hWnd)
pGraphics = 0
GdipCreateFromHDC(hDC, @pGraphics)
GdipDrawImageRectI(pGraphics, pImage, nX, nY, nWidth, nHeight)
GdipDisposeImage(pImage)
GdipDeleteGraphics(pGraphics)
ReleaseDC(hWnd, hDC)
ENDFUNC
运行后的效果图如下:
只有本站会员才能查看附件,请 登录