UID 1 精华 积分 77054 威望  点 
宅币  个 
贡献  次 
宅之契约  份 
最后登录 1970-1-1 
在线时间  小时 
 
 
 
 
 
 
这里所说的高细节并不是我们所说的HDR,也不是用浮点数进行纹理存储……而是在尽可能保证图片不变得“难看”的情况下把图片降级为256色(尤其是对于存储GIF图片非常具有利用价值)。Palette (或颜色表 Color Table )。这个颜色表是如何得到的呢?有很多种方法:【C】八叉树算法:BMP颜色降级生成调色板的算法 
 
 
 
 
亲测效果不好用,请大家不要用。 
 
 
 
 
 
 
 
 
 
VERSION 5.00 Begin VB.Form frmMain     Caption         =   "取得调色板"    ClientHeight    =   6465    ClientLeft      =   120    ClientTop       =   450    ClientWidth     =   16440    LinkTopic       =   "frmMain"    OLEDropMode     =   1  'Manual    ScaleHeight     =   431    ScaleMode       =   3  'Pixel    ScaleWidth      =   1096    StartUpPosition =   3  '窗口缺省    Begin VB.PictureBox picDither        Align           =   3  'Align Left       BorderStyle     =   0  'None       Height          =   6465       Left            =   0       ScaleHeight     =   431       ScaleMode       =   3  'Pixel       ScaleWidth      =   457       TabIndex        =   6       Top             =   0       Visible         =   0   'False       Width           =   6855       Begin VB.HScrollBar HSDither           Height          =   255          Left            =   1440          Max             =   0          TabIndex        =   12          TabStop         =   0   'False          Top             =   3000          Width           =   2415       End       Begin VB.PictureBox picColor4           AutoRedraw      =   -1  'True          BackColor       =   &H00000000&          BorderStyle     =   0  'None          Height          =   495          Left            =   1800          ScaleHeight     =   33          ScaleMode       =   3  'Pixel          ScaleWidth      =   33          TabIndex        =   11          Top             =   0          Visible         =   0   'False          Width           =   495       End       Begin VB.PictureBox picColor3           AutoRedraw      =   -1  'True          BackColor       =   &H00000000&          BorderStyle     =   0  'None          Height          =   495          Left            =   1200          ScaleHeight     =   33          ScaleMode       =   3  'Pixel          ScaleWidth      =   33          TabIndex        =   10          Top             =   0          Visible         =   0   'False          Width           =   495       End       Begin VB.PictureBox picColor2           AutoRedraw      =   -1  'True          BackColor       =   &H00000000&          BorderStyle     =   0  'None          Height          =   495          Left            =   600          ScaleHeight     =   33          ScaleMode       =   3  'Pixel          ScaleWidth      =   33          TabIndex        =   9          Top             =   0          Visible         =   0   'False          Width           =   495       End       Begin VB.PictureBox picColor1           AutoRedraw      =   -1  'True          BackColor       =   &H00000000&          BorderStyle     =   0  'None          Height          =   495          Left            =   0          ScaleHeight     =   33          ScaleMode       =   3  'Pixel          ScaleWidth      =   33          TabIndex        =   8          Top             =   0          Visible         =   0   'False          Width           =   495       End       Begin VB.PictureBox picResult           AutoRedraw      =   -1  'True          BackColor       =   &H00000000&          BorderStyle     =   0  'None          Height          =   495          Left            =   2400          ScaleHeight     =   33          ScaleMode       =   3  'Pixel          ScaleWidth      =   33          TabIndex        =   7          Top             =   0          Visible         =   0   'False          Width           =   495       End    End    Begin VB.PictureBox picRightPanel        Align           =   4  'Align Right       BorderStyle     =   0  'None       Height          =   6465       Left            =   15345       ScaleHeight     =   431       ScaleMode       =   3  'Pixel       ScaleWidth      =   73       TabIndex        =   0       Top             =   0       Width           =   1095       Begin VB.PictureBox picProgress           BackColor       =   &H8000000C&          Height          =   255          Left            =   0          ScaleHeight     =   13          ScaleMode       =   3  'Pixel          ScaleWidth      =   69          TabIndex        =   14          Top             =   4320          Width           =   1095          Begin VB.CommandButton cmdProgress              Enabled         =   0   'False             Height          =   195             Left            =   0             Style           =   1  'Graphical             TabIndex        =   15             Top             =   0             Width           =   1035          End       End       Begin VB.CheckBox ChRandomPalette           Caption         =   "产生随机调色板"          Height          =   615          Left            =   0          Style           =   1  'Graphical          TabIndex        =   13          Top             =   3600          Width           =   1095       End       Begin VB.PictureBox picPal           AutoRedraw      =   -1  'True          BackColor       =   &H00000000&          BorderStyle     =   0  'None          Height          =   1095          Left            =   0          ScaleHeight     =   73          ScaleMode       =   3  'Pixel          ScaleWidth      =   73          TabIndex        =   5          Top             =   2400          Width           =   1095       End       Begin VB.OptionButton OpDitherPic           Caption         =   "抖动图"          Enabled         =   0   'False          Height          =   495          Left            =   0          Style           =   1  'Graphical          TabIndex        =   4          Top             =   1920          Value           =   -1  'True          Width           =   1095       End       Begin VB.OptionButton OpSrcPic           Caption         =   "原图"          Enabled         =   0   'False          Height          =   495          Left            =   0          Style           =   1  'Graphical          TabIndex        =   3          Top             =   1440          Width           =   1095       End       Begin VB.CommandButton cmdDither           Caption         =   "抖动"          Enabled         =   0   'False          Height          =   615          Left            =   0          TabIndex        =   1          Top             =   0          Width           =   1095       End    End    Begin VB.PictureBox picSrcPic        AutoRedraw      =   -1  'True       AutoSize        =   -1  'True       BorderStyle     =   0  'None       Height          =   255       Left            =   0       ScaleHeight     =   255       ScaleWidth      =   135       TabIndex        =   2       Top             =   0       Visible         =   0   'False       Width           =   135    End End Attribute VB_Name = "frmMain" Attribute VB_GlobalNameSpace = False Attribute VB_Creatable = False Attribute VB_PredeclaredId = True Attribute VB_Exposed = False '============================================================================== '作者:0xAA55 '论坛:http://www.0xaa55.com/ '版权所有 (C) 2013-2014 技术宅的结界 '请保留原作者信息,否则视为侵权。 '------------------------------------------------------------------------------ Option Explicit Private Const COLORS_MAX As Long = 256 Private Const COLORS_BITS As Long = 8 Private Const DIST_MAX As Long = 200000 Private Type RGBQUAD     B As Byte     G As Byte     R As Byte     X As Byte End Type Private Type BITMAPINFO24     biSize As Long     biWidth As Long     biHeight As Long     biPlanes As Integer     biBitCount As Integer     biCompression As Long     biSizeImage As Long     biXPelsPerMeter As Long     biYPelsPerMeter As Long     biClrUsed As Long     biClrImportant As Long End Type Private Type BITMAPINFOPAL     biSize As Long     biWidth As Long     biHeight As Long     biPlanes As Integer     biBitCount As Integer     biCompression As Long     biSizeImage As Long     biXPelsPerMeter As Long     biYPelsPerMeter As Long     biClrUsed As Long     biClrImportant As Long     Palette(COLORS_MAX - 1) As RGBQUAD End Type Private Declare Function CreateOctreePaletteFromHBITMAP Lib "..\Octree.dll" (ByVal hDC&, ByVal hBitmap&, ByVal Width&, ByVal Height&, ByVal MaxColors&, ByVal ColorBits&, P As RGBQUAD) As Long Private Declare Function GetBitmapPitch Lib "..\Octree.dll" (ByVal BitCount As Integer, ByVal Width As Long) As Long Private Declare Function GetDIBits Lib "gdi32.dll" (ByVal aHDC As Long, ByVal hBitmap As Long, ByVal nStartScan As Long, ByVal nNumScans As Long, lpBits As Any, lpBI As BITMAPINFO24, ByVal wUsage As Long) As Long Private Declare Function SetDIBits Lib "gdi32.dll" (ByVal aHDC As Long, ByVal hBitmap As Long, ByVal nStartScan As Long, ByVal nNumScans As Long, lpBits As Any, lpBI As BITMAPINFOPAL, ByVal wUsage As Long) As Long Private Const DIB_RGB_COLORS = 0 '  color table in RGBs Private Const DIB_PAL_COLORS = 1 '  color table in palette indices Dim BMIF24 As BITMAPINFO24 Dim BMIFPAL As BITMAPINFOPAL Dim PW&, PH& Dim LM() As Byte Dim QuitLoop As Boolean Dim SrcPixels() As Byte Dim Values1() As Byte Dim Values2() As Byte Dim Values3() As Byte Dim Values4() As Byte Dim Vec1R() As Long, Vec1G() As Long, Vec1B() As Long Dim Vec2R() As Long, Vec2G() As Long, Vec2B() As Long Dim Vec3R() As Long, Vec3G() As Long, Vec3B() As Long Dim Vec4R() As Long, Vec4G() As Long, Vec4B() As Long Private Const MaxDist As Double = 64 Private Const MaxDistSq As Double = MaxDist * MaxDist Private Const RefreshInterval As Single = 0.1 Dim ProgWidth As Single Sub DrawProgress(ByVal Prog As Double) cmdProgress.Left = (Prog - 1) * ProgWidth picProgress.Refresh End Sub Private Sub cmdDither_Click() Dim DestPixels() As Byte Dim Pitch1 As Long, Pitch2 As Long Dim X&, Y& Dim I&, LStart1& Dim L&, LStart2& Dim K&, DistanceSq As Long, NewDistSq As Long Dim RDiff As Long, GDiff As Long, BDiff As Long Dim Tm!, NTm! cmdDither.Enabled = False picDither.Visible = True picDither.Visible = True Form_Resize Pitch1 = GetBitmapPitch(24, PW) Pitch2 = GetBitmapPitch(8, PW) Erase Values1, Values2, Values3, Values4, SrcPixels Erase Vec1R, Vec1G, Vec1B Erase Vec2R, Vec2G, Vec2B Erase Vec3R, Vec3G, Vec3B Erase Vec4R, Vec4G, Vec4B ReDim SrcPixels(Pitch1 * PH - 1) ReDim DestPixels(Pitch2 * PH - 1) ReDim Values1(UBound(DestPixels)) ReDim Values2(UBound(DestPixels)) ReDim Values3(UBound(DestPixels)) ReDim Values4(UBound(DestPixels)) ReDim Vec1R(UBound(DestPixels)), Vec1G(UBound(DestPixels)), Vec1B(UBound(DestPixels)) ReDim Vec2R(UBound(DestPixels)), Vec2G(UBound(DestPixels)), Vec2B(UBound(DestPixels)) ReDim Vec3R(UBound(DestPixels)), Vec3G(UBound(DestPixels)), Vec3B(UBound(DestPixels)) ReDim Vec4R(UBound(DestPixels)), Vec4G(UBound(DestPixels)), Vec4B(UBound(DestPixels)) GetDIBits picSrcPic.hDC, picSrcPic.Image.Handle, 0, PH, SrcPixels(0), BMIF24, DIB_RGB_COLORS '============================================================================== '步骤1:取得最相近的颜色 '------------------------------------------------------------------------------ LStart1 = 0 LStart2 = 0 picColor1.Visible = True For Y = 0 To PH - 1     I = LStart1     L = LStart2     For X = 0 To PW - 1         DistanceSq = 255& * 255 * 3         For K = 0 To 255             RDiff = CLng(BMIFPAL.Palette(K).R) - SrcPixels(I + 2)             GDiff = CLng(BMIFPAL.Palette(K).G) - SrcPixels(I + 1)             BDiff = CLng(BMIFPAL.Palette(K).B) - SrcPixels(I + 0)             NewDistSq = RDiff * RDiff + GDiff * GDiff + BDiff * BDiff             If NewDistSq < DistanceSq And NewDistSq <= MaxDistSq Then                 Vec1R(L) = RDiff                 Vec1G(L) = GDiff                 Vec1B(L) = BDiff                 Values1(L) = K                 DestPixels(L) = K                 DistanceSq = NewDistSq             End If         Next         I = I + 3         L = L + 1     Next     NTm = Timer     If NTm - Tm >= RefreshInterval Then         Tm = NTm         SetDIBits picColor1.hDC, picColor1.Image.Handle, 0, PH, DestPixels(0), BMIFPAL, DIB_RGB_COLORS         picColor1.PaintPicture picSrcPic.Image, 0, 0, PW, PH - Y, 0, 0, PW, PH - Y         DrawProgress Y / (PH - 1)         picColor1.Refresh         DoEvents         If QuitLoop Then Exit For     End If     LStart1 = LStart1 + Pitch1     LStart2 = LStart2 + Pitch2 Next SetDIBits picColor1.hDC, picColor1.Image.Handle, 0, PH, DestPixels(0), BMIFPAL, DIB_RGB_COLORS DrawProgress 1 picColor1.Refresh '============================================================================== '步骤2:取得和上一步相反的颜色 '------------------------------------------------------------------------------ LStart1 = 0 LStart2 = 0 picColor2.Visible = True For Y = 0 To PH - 1     I = LStart1     L = LStart2     For X = 0 To PW - 1         DistanceSq = 255& * 255 * 3         Values2(L) = Values1(L)         For K = 0 To 255             RDiff = CLng(BMIFPAL.Palette(K).R) - SrcPixels(I + 2)             GDiff = CLng(BMIFPAL.Palette(K).G) - SrcPixels(I + 1)             BDiff = CLng(BMIFPAL.Palette(K).B) - SrcPixels(I + 0)             If RDiff * Vec1R(L) + GDiff * Vec1G(L) + BDiff * Vec1B(L) < 0 Then                 NewDistSq = RDiff * RDiff + GDiff * GDiff + BDiff * BDiff                 If NewDistSq < DistanceSq And NewDistSq <= MaxDistSq Then                     Vec2R(L) = RDiff                     Vec2G(L) = GDiff                     Vec2B(L) = BDiff                     Values2(L) = K                     DestPixels(L) = K                     DistanceSq = NewDistSq                 End If             End If         Next         I = I + 3         L = L + 1     Next     NTm = Timer     If NTm - Tm >= RefreshInterval Then         Tm = NTm         SetDIBits picColor2.hDC, picColor2.Image.Handle, 0, PH, DestPixels(0), BMIFPAL, DIB_RGB_COLORS         DrawProgress Y / (PH - 1)         picColor2.Refresh         DoEvents         If QuitLoop Then Exit For     End If     LStart1 = LStart1 + Pitch1     LStart2 = LStart2 + Pitch2 Next SetDIBits picColor2.hDC, picColor2.Image.Handle, 0, PH, DestPixels(0), BMIFPAL, DIB_RGB_COLORS DrawProgress 1 picColor2.Refresh '============================================================================== '步骤3:取得和上两步相反的颜色 '------------------------------------------------------------------------------ LStart1 = 0 LStart2 = 0 picColor3.Visible = True For Y = 0 To PH - 1     I = LStart1     L = LStart2     For X = 0 To PW - 1         DistanceSq = 255& * 255 * 3         Values3(L) = Values2(L)         For K = 0 To 255             RDiff = CLng(BMIFPAL.Palette(K).R) - SrcPixels(I + 2)             GDiff = CLng(BMIFPAL.Palette(K).G) - SrcPixels(I + 1)             BDiff = CLng(BMIFPAL.Palette(K).B) - SrcPixels(I + 0)             If RDiff * Vec1R(L) + GDiff * Vec1G(L) + BDiff * Vec1B(L) < 0 And _                RDiff * Vec2R(L) + GDiff * Vec2G(L) + BDiff * Vec2B(L) < 0 Then                 NewDistSq = RDiff * RDiff + GDiff * GDiff + BDiff * BDiff                 If NewDistSq < DistanceSq And NewDistSq <= MaxDistSq Then                     Vec3R(L) = RDiff                     Vec3G(L) = GDiff                     Vec3B(L) = BDiff                     Values3(L) = K                     DestPixels(L) = K                     DistanceSq = NewDistSq                 End If             End If         Next         I = I + 3         L = L + 1     Next     NTm = Timer     If NTm - Tm >= RefreshInterval Then         Tm = NTm         SetDIBits picColor3.hDC, picColor3.Image.Handle, 0, PH, DestPixels(0), BMIFPAL, DIB_RGB_COLORS         DrawProgress Y / (PH - 1)         picColor3.Refresh         DoEvents         If QuitLoop Then Exit For     End If     LStart1 = LStart1 + Pitch1     LStart2 = LStart2 + Pitch2 Next SetDIBits picColor3.hDC, picColor3.Image.Handle, 0, PH, DestPixels(0), BMIFPAL, DIB_RGB_COLORS DrawProgress 1 picColor3.Refresh '============================================================================== '步骤4:取得和上三步相反的颜色 '------------------------------------------------------------------------------ LStart1 = 0 LStart2 = 0 picColor4.Visible = True For Y = 0 To PH - 1     I = LStart1     L = LStart2     For X = 0 To PW - 1         DistanceSq = 255& * 255 * 3         Values4(L) = Values3(L)         For K = 0 To 255             RDiff = CLng(BMIFPAL.Palette(K).R) - SrcPixels(I + 2)             GDiff = CLng(BMIFPAL.Palette(K).G) - SrcPixels(I + 1)             BDiff = CLng(BMIFPAL.Palette(K).B) - SrcPixels(I + 0)             If RDiff * Vec1R(L) + GDiff * Vec1G(L) + BDiff * Vec1B(L) < 0 And _                RDiff * Vec2R(L) + GDiff * Vec2G(L) + BDiff * Vec2B(L) < 0 And _                RDiff * Vec3R(L) + GDiff * Vec3G(L) + BDiff * Vec3B(L) < 0 Then                 NewDistSq = RDiff * RDiff + GDiff * GDiff + BDiff * BDiff                 If NewDistSq < DistanceSq And NewDistSq <= MaxDistSq Then                     Vec4R(L) = RDiff                     Vec4G(L) = GDiff                     Vec4B(L) = BDiff                     Values4(L) = K                     DestPixels(L) = K                     DistanceSq = NewDistSq                 End If             End If         Next         I = I + 3         L = L + 1     Next     NTm = Timer     If NTm - Tm >= RefreshInterval Then         Tm = NTm         SetDIBits picColor4.hDC, picColor4.Image.Handle, 0, PH, DestPixels(0), BMIFPAL, DIB_RGB_COLORS         DrawProgress Y / (PH - 1)         picColor4.Refresh         DoEvents         If QuitLoop Then Exit For     End If     LStart1 = LStart1 + Pitch1     LStart2 = LStart2 + Pitch2 Next SetDIBits picColor4.hDC, picColor4.Image.Handle, 0, PH, DestPixels(0), BMIFPAL, DIB_RGB_COLORS DrawProgress 1 picColor4.Refresh '============================================================================== '步骤5:将上面四步取得的颜色进行抖动混合 '------------------------------------------------------------------------------ LStart1 = 0 LStart2 = 0 picResult.Visible = True Dim DitherValue As Long For Y = 0 To PH - 1     I = LStart1     L = LStart2     For X = 0 To PW - 1         DitherValue = LM((X And &HF) + (Y And &HF) * &H10)         If Values1(L) = Values2(L) And Values2(L) = Values3(L) And Values3(L) = Values4(L) Then '只有一个颜色             DestPixels(L) = Values1(L)         ElseIf Values1(L) <> Values2(L) And Values2(L) = Values3(L) And Values3(L) = Values4(L) Then '抖动颜色1、2                          '          Src             '           /|~"-,_             '          / |     ~"-,_             '         /  |          ~"-,_             '        /   |               ~"-,_             '       /    |                    ~"-,_             'Values1~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Values2                          Dim Vec1To2R As Long, Vec1To2G As Long, Vec1To2B As Long             Dim Vec1To2Dist As Double, ProjLen As Double             Vec1To2R = Vec2R(L) - Vec1R(L)             Vec1To2G = Vec2G(L) - Vec1G(L)             Vec1To2B = Vec2B(L) - Vec1B(L)             Vec1To2Dist = Sqr(CDbl(Vec1To2R) * Vec1To2R + CDbl(Vec1To2G) * Vec1To2G + CDbl(Vec1To2B) * Vec1To2B)             ProjLen = (-Vec1R(L) * Vec1To2R - Vec1G(L) * Vec1To2G - Vec1B(L) * Vec1To2B) / Vec1To2Dist             If ProjLen * 255 / Vec1To2Dist <= DitherValue Then DestPixels(L) = Values1(L) Else DestPixels(L) = Values2(L)         ElseIf Values1(L) <> Values2(L) And Values2(L) <> Values3(L) And Values3(L) = Values4(L) Then '抖动颜色1、2、3                          'P2,             '|\ ~"-,_             '| \     ~"-,_             '|  P,__      ~"-,_             '| /    ~~""--,,__ ~"-,_             '|L               ~~""--===,_             'P1~~~~~~~~~~~~~~~~~~~~~~~~~~~P3                          Dim Plane123A As Double, Plane123B As Double, Plane123C As Double, Plane123D As Double             Dim Plane123ABCLen As Double             Dim Vec2To3R As Long, Vec2To3G As Long, Vec2To3B As Long             Vec1To2R = Vec2R(L) - Vec1R(L)             Vec1To2G = Vec2G(L) - Vec1G(L)             Vec1To2B = Vec2B(L) - Vec1B(L)             Vec2To3R = Vec3R(L) - Vec2R(L)             Vec2To3G = Vec3G(L) - Vec2G(L)             Vec2To3B = Vec3B(L) - Vec2B(L)                          Plane123A = Vec1To2G * Vec2To3B - Vec1To2B * Vec2To3G             Plane123B = Vec1To2B * Vec2To3R - Vec1To2R * Vec2To3B             Plane123C = Vec1To2R * Vec2To3G - Vec1To2G * Vec2To3R             Plane123D = -(Plane123A * BMIFPAL.Palette(Values1(L)).R + Plane123B * BMIFPAL.Palette(Values1(L)).G + Plane123C * BMIFPAL.Palette(Values1(L)).B)                          Plane123ABCLen = Sqr(Plane123A * Plane123A + Plane123B * Plane123B + Plane123C * Plane123C)             Plane123A = Plane123A / Plane123ABCLen             Plane123B = Plane123B / Plane123ABCLen             Plane123C = Plane123C / Plane123ABCLen             Plane123D = Plane123D / Plane123ABCLen                          Dim PlaneFace23A As Double, PlaneFace23B As Double, PlaneFace23C As Double, PlaneFace23D As Double             Dim PlaneFace23ABCLen As Double             PlaneFace23A = Vec1G(L) * Plane123C - Vec1B(L) * Plane123B             PlaneFace23B = Vec1B(L) * Plane123A - Vec1R(L) * Plane123C             PlaneFace23C = Vec1R(L) * Plane123B - Vec1G(L) * Plane123A             PlaneFace23D = -(PlaneFace23A * SrcPixels(I + 2) + PlaneFace23B * SrcPixels(I + 1) + PlaneFace23C * SrcPixels(I + 0))                          PlaneFace23ABCLen = Sqr(PlaneFace23A * PlaneFace23A + PlaneFace23B * PlaneFace23B + PlaneFace23C * PlaneFace23C)             PlaneFace23A = PlaneFace23A / PlaneFace23ABCLen             PlaneFace23B = PlaneFace23B / PlaneFace23ABCLen             PlaneFace23C = PlaneFace23C / PlaneFace23ABCLen             PlaneFace23D = PlaneFace23D / PlaneFace23ABCLen                          Dim P2ToPlaneDist As Double, P3ToPlaneDist As Double, PlaneCutPosition As Double             P2ToPlaneDist = Abs(BMIFPAL.Palette(Values2(L)).R * PlaneFace23A + BMIFPAL.Palette(Values2(L)).G * PlaneFace23B + BMIFPAL.Palette(Values2(L)).B * PlaneFace23C + PlaneFace23D)             P3ToPlaneDist = Abs(BMIFPAL.Palette(Values3(L)).R * PlaneFace23A + BMIFPAL.Palette(Values3(L)).G * PlaneFace23B + BMIFPAL.Palette(Values3(L)).B * PlaneFace23C + PlaneFace23D)             PlaneCutPosition = P2ToPlaneDist / (P2ToPlaneDist + P3ToPlaneDist)                          If PlaneCutPosition * 255 <= DitherValue Then DestPixels(L) = Values2(L) Else DestPixels(L) = Values3(L)                          Dim PointOnPlaneAnd2To3VecR As Double, PointOnPlaneAnd2To3VecG As Double, PointOnPlaneAnd2To3VecB As Double             PointOnPlaneAnd2To3VecR = CDbl(BMIFPAL.Palette(Values2(L)).R) + Vec2To3R * PlaneCutPosition - SrcPixels(I + 2)             PointOnPlaneAnd2To3VecG = CDbl(BMIFPAL.Palette(Values2(L)).G) + Vec2To3G * PlaneCutPosition - SrcPixels(I + 1)             PointOnPlaneAnd2To3VecB = CDbl(BMIFPAL.Palette(Values2(L)).B) + Vec2To3B * PlaneCutPosition - SrcPixels(I + 0)                          Dim VecToThatPointR As Double, VecToThatPointG As Double, VecToThatPointB As Double, VecToThatPointLen As Double             VecToThatPointR = PointOnPlaneAnd2To3VecR - Vec1R(L)             VecToThatPointG = PointOnPlaneAnd2To3VecG - Vec1G(L)             VecToThatPointB = PointOnPlaneAnd2To3VecB - Vec1B(L)             VecToThatPointLen = Sqr(VecToThatPointR * VecToThatPointR + VecToThatPointG * VecToThatPointG + VecToThatPointB * VecToThatPointB)             VecToThatPointR = VecToThatPointR / VecToThatPointLen             VecToThatPointG = VecToThatPointG / VecToThatPointLen             VecToThatPointB = VecToThatPointB / VecToThatPointLen                          ProjLen = (-Vec1R(L) * VecToThatPointR - Vec1G(L) * VecToThatPointG - Vec1B(L) * VecToThatPointB) / VecToThatPointLen                          If ProjLen * 255 <= DitherValue Then DestPixels(L) = Values1(L)                      Else '抖动颜色1、2、3、4             Dim Plane12PA As Double, Plane12PB As Double, Plane12PC As Double, Plane12PD As Double, Plane12PABCLen As Double             Dim Plane34PA As Double, Plane34PB As Double, Plane34PC As Double, Plane34PD As Double, Plane34PABCLen As Double                          Plane12PA = Vec1G(L) * Vec2B(L) - Vec1B(L) * Vec2G(L)             Plane12PB = Vec1B(L) * Vec2R(L) - Vec1R(L) * Vec2B(L)             Plane12PC = Vec1R(L) * Vec2G(L) - Vec1G(L) * Vec2R(L)                          Plane34PA = Vec3G(L) * Vec4B(L) - Vec3B(L) * Vec4G(L)             Plane34PB = Vec3B(L) * Vec4R(L) - Vec3R(L) * Vec4B(L)             Plane34PC = Vec3R(L) * Vec4G(L) - Vec3G(L) * Vec4R(L)                          Plane12PD = -(Plane12PA * SrcPixels(I + 2) + Plane12PB * SrcPixels(I + 1) + Plane12PC * SrcPixels(I + 0))             Plane34PD = -(Plane34PA * SrcPixels(I + 2) + Plane34PB * SrcPixels(I + 1) + Plane34PC * SrcPixels(I + 0))                          Plane12PABCLen = Sqr(Plane12PA * Plane12PA + Plane12PB * Plane12PB + Plane12PC * Plane12PC)             Plane34PABCLen = Sqr(Plane34PA * Plane34PA + Plane34PB * Plane34PB + Plane34PC * Plane34PC)                          Plane12PA = Plane12PA / Plane12PABCLen             Plane12PB = Plane12PB / Plane12PABCLen             Plane12PC = Plane12PC / Plane12PABCLen             Plane12PD = Plane12PD / Plane12PABCLen                          Plane34PA = Plane34PA / Plane34PABCLen             Plane34PB = Plane34PB / Plane34PABCLen             Plane34PC = Plane34PC / Plane34PABCLen             Plane34PD = Plane34PD / Plane34PABCLen                          Dim Distance1ToP34 As Double, Distance2ToP34 As Double             Dim Distance3ToP12 As Double, Distance4ToP12 As Double                          Distance1ToP34 = Abs(Vec1R(L) * Plane34PA + Vec1G(L) * Plane34PB + Vec1B(L) * Plane34PC + Plane34PD)             Distance2ToP34 = Abs(Vec2R(L) * Plane34PA + Vec2G(L) * Plane34PB + Vec2B(L) * Plane34PC + Plane34PD)             Distance3ToP12 = Abs(Vec3R(L) * Plane12PA + Vec3G(L) * Plane12PB + Vec3B(L) * Plane12PC + Plane12PD)             Distance4ToP12 = Abs(Vec4R(L) * Plane12PA + Vec4G(L) * Plane12PB + Vec4B(L) * Plane12PC + Plane12PD)                          Dim P12Cut34 As Double, P34Cut12 As Double             P12Cut34 = Distance3ToP12 + (Distance3ToP12 + Distance4ToP12)             P34Cut12 = Distance1ToP34 + (Distance1ToP34 + Distance2ToP34)                          Dim Value12 As Byte, Value34 As Byte             If P12Cut34 * 255 <= DitherValue Then Value34 = Values3(L) Else Value34 = Values4(L)             If P34Cut12 * 255 <= DitherValue Then Value12 = Values1(L) Else Value12 = Values2(L)                          Vec1To2R = Vec2R(L) - Vec1R(L)             Vec1To2G = Vec2G(L) - Vec1G(L)             Vec1To2B = Vec2B(L) - Vec1B(L)             Dim Vec3To4R As Long, Vec3To4G As Long, Vec3To4B As Long             Vec3To4R = Vec4R(L) - Vec3R(L)             Vec3To4G = Vec4G(L) - Vec3G(L)             Vec3To4B = Vec4B(L) - Vec3B(L)                          Dim CutPoint1R As Double, CutPoint1G As Double, CutPoint1B As Double             Dim CutPoint2R As Double, CutPoint2G As Double, CutPoint2B As Double                          CutPoint1R = Vec1R(L) + Vec1To2R * P34Cut12             CutPoint1G = Vec1G(L) + Vec1To2G * P34Cut12             CutPoint1B = Vec1B(L) + Vec1To2B * P34Cut12                          CutPoint2R = Vec3R(L) + Vec3To4R * P12Cut34             CutPoint2G = Vec3G(L) + Vec3To4G * P12Cut34             CutPoint2B = Vec3B(L) + Vec3To4B * P12Cut34                          Dim Dist12 As Double, Dist34 As Double             Dist12 = Sqr(CutPoint1R * CutPoint1R + CutPoint1G * CutPoint1G + CutPoint1B * CutPoint1B)             Dist34 = Sqr(CutPoint2R * CutPoint2R + CutPoint2G * CutPoint2G + CutPoint2B * CutPoint2B)                      If Dist12 * 255 / (Dist12 + Dist34) <= DitherValue Then DestPixels(L) = Value12 Else DestPixels(L) = Value34                      End If         I = I + 3         L = L + 1     Next     NTm = Timer     If NTm - Tm >= RefreshInterval Then         Tm = NTm         SetDIBits picResult.hDC, picResult.Image.Handle, 0, PH, DestPixels(0), BMIFPAL, DIB_RGB_COLORS         DrawProgress Y / (PH - 1)         picResult.Refresh         DoEvents         If QuitLoop Then Exit For     End If     LStart1 = LStart1 + Pitch1     LStart2 = LStart2 + Pitch2 Next SetDIBits picResult.hDC, picResult.Image.Handle, 0, PH, DestPixels(0), BMIFPAL, DIB_RGB_COLORS DrawProgress 1 picResult.Refresh cmdDither.Enabled = False OpSrcPic.Enabled = True OpDitherPic.Enabled = True OpDitherPic.Value = True End Sub Private Sub Form_Load() With BMIF24     .biSize = 40     .biPlanes = 1     .biBitCount = 24 End With With BMIFPAL     .biSize = 40     .biPlanes = 1     .biBitCount = COLORS_BITS     .biClrUsed = COLORS_MAX     .biClrImportant = COLORS_MAX End With LM = LoadResData(101, "LIGHTMATRIX") Randomize Timer ProgWidth = picProgress.ScaleWidth End Sub Function Lerp(ByVal V1 As Long, ByVal V2 As Long, ByVal Val_0_255 As Long) As Long Lerp = V1 + (V2 - V1) * Val_0_255 \ 255 End Function Private Sub Form_OLEDragDrop(Data As DataObject, Effect As Long, Button As Integer, Shift As Integer, X As Single, Y As Single) On Local Error GoTo eHandlr Picture = LoadPicture(Data.Files(1)) PW = ScaleX(Picture.Width, vbHimetric, vbPixels) PH = ScaleY(Picture.Height, vbHimetric, vbPixels) picSrcPic.Move 0, 0, PW, PH picSrcPic.PaintPicture Picture, 0, 0 picColor1.Cls picColor2.Cls picColor3.Cls picColor4.Cls picResult.Cls picColor1.Visible = False picColor2.Visible = False picColor3.Visible = False picColor4.Visible = False picResult.Visible = False picColor1.Move PW * 0, 0, PW, PH picColor2.Move PW * 1, 0, PW, PH picColor3.Move PW * 2, 0, PW, PH picColor4.Move PW * 3, 0, PW, PH picResult.Move PW * 4, 0, PW, PH picDither_Resize HSDither_Change BMIF24.biWidth = PW BMIF24.biHeight = PH BMIFPAL.biWidth = PW BMIFPAL.biHeight = PH DrawProgress 0 If ChRandomPalette.Value Then     Dim I&     For I = 0 To UBound(BMIFPAL.Palette)         BMIFPAL.Palette(I).R = Rnd * 255         BMIFPAL.Palette(I).G = Rnd * 255         BMIFPAL.Palette(I).B = Rnd * 255     Next Else     If CreateOctreePaletteFromHBITMAP(hDC, Picture.Handle, PW, PH, COLORS_MAX, COLORS_BITS, BMIFPAL.Palette(0)) = 0 Then         MsgBox "生成调色板失败。", vbExclamation     End If End If DrawPal cmdDither.Enabled = True OpSrcPic.Enabled = False OpDitherPic.Enabled = False OpSrcPic.Value = True Exit Sub eHandlr: MsgBox Err.Description, vbExclamation, "出错" End Sub Sub DrawPal() Dim X&, Y& Dim DrX&, DrY& Dim I& For Y = 0 To 15     DrX = 0     For X = 0 To 15         picPal.Line (DrX, DrY)-(DrX + 4, DrY + 4), RGB(BMIFPAL.Palette(I).R, BMIFPAL.Palette(I).G, BMIFPAL.Palette(I).B), BF         I = I + 1         If I >= COLORS_MAX Then Exit Sub         DrX = DrX + 5     Next     DrY = DrY + 5 Next End Sub Private Sub Form_Resize() On Error Resume Next picDither.Width = picRightPanel.Left End Sub Private Sub Form_Unload(Cancel As Integer) QuitLoop = True End End Sub Private Sub HSDither_Change() On Error Resume Next Dim LeftBegin As Long LeftBegin = -HSDither.Value picColor1.Left = LeftBegin + PW * 0 picColor2.Left = LeftBegin + PW * 1 picColor3.Left = LeftBegin + PW * 2 picColor4.Left = LeftBegin + PW * 3 picResult.Left = LeftBegin + PW * 4 End Sub Private Sub HSDither_Scroll() HSDither_Change End Sub Private Sub OpDitherPic_Click() picSrcPic.Visible = False picDither.Visible = True End Sub Private Sub OpSrcPic_Click() picSrcPic.Visible = True picDither.Visible = False End Sub Private Sub picDither_Resize() On Error Resume Next Dim PP1W As Long, PP1H As Long, HSMax As Long PP1W = picDither.ScaleWidth PP1H = picDither.ScaleHeight HSDither.Move 0, PP1H - 17, PP1W, 17 HSMax = PW * 5 - PP1W If HSMax > 0 Then     HSDither.Max = HSMax     HSDither.LargeChange = PP1W     HSDither.Visible = True Else     HSDither.Value = 0     HSDither.Visible = False End If End Sub 复制代码 
取得调色板.exe 
(64 KB, 下载次数: 19, 售价: 1 个宅币) 
 
 
取得调色板.7z 
(33.14 KB, 下载次数: 10, 售价: 10 个宅币)