Eric's Pixel Expansion (EPX) is an algorithm developed by Eric Johnston at LucasArts around 1992, when porting the SCUMM engine games from the IBM PC (which ran at 320×200×256 colors)
to the early color Macintosh computers, which ran at more or less double that resolution.The algorithm works as follows:
A --\ 1 2
C P B --/ 3 4
D
1=P; 2=P; 3=P; 4=P;
IF C==A => 1=A
IF A==B => 2=B
IF D==C => 3=C
IF B==D => 4=D
IF of A, B, C, D, three or more are identical: 1=2=3=4=P
Later implementations of this same algorithm (as AdvMAME2× and Scale2×, developed around 2001) have a slightly more efficient but functionally identical implementation:
A --\ 1 2
C P B --/ 3 4
D
1=P; 2=P; 3=P; 4=P;
IF C==A AND C!=D AND A!=B => 1=A
IF A==B AND A!=C AND B!=D => 2=B
IF D==C AND D!=B AND C!=A => 3=C
IF B==D AND B!=A AND D!=C => 4=D
PB code
Code: Select all
Macro S
x-1,y-1
EndMacro
Macro U
x+1,y-1
EndMacro
Macro R
x-1,y+1
EndMacro
Macro Z
x+1,y+1
EndMacro
Macro A
x,y-1
EndMacro
Macro B
x+1,y
EndMacro
Macro C
x-1,y
EndMacro
Macro D
x,y+1
EndMacro
Macro P
x,y
EndMacro
Macro N1
x*2,y*2
EndMacro
Macro N2
x*2+1,y*2
EndMacro
Macro N3
x*2,y*2+1
EndMacro
Macro N4
x*2+1,y*2+1
EndMacro
Procedure Scale2x(Img)
; A --\ 1 2
; C P B --/ 3 4
; D
; 1=P; 2=P; 3=P; 4=P;
; IF C==A AND C!=D AND A!=B => 1=A
; IF A==B AND A!=C AND B!=D => 2=B
; IF B==D AND B!=A AND D!=C => 4=D
; IF D==C AND D!=B AND C!=A => 3=C
Dim Colors(ImageWidth(Img),ImageHeight(Img))
Dim NewColors(ImageWidth(Img)*2,ImageHeight(Img)*2)
StartDrawing( ImageOutput(Img))
For y = 0 To ImageHeight(Img)-1
For x = 0 To ImageWidth(Img) -1
Colors(x,y) = Point(x, y)
Next
Next
StopDrawing()
For y = 1 To ImageHeight(Img) -1
For x = 1 To ImageWidth(Img)-1
NewColors(N1) = Colors(P):NewColors(N2) = Colors(P): NewColors(N3) = Colors(P):NewColors(N4)= Colors(P)
If Colors(C)=Colors(A) And Colors(C)<>Colors(D) And Colors(A)<>Colors(B):NewColors(N1) = Colors(A):EndIf
If Colors(A)=Colors(B) And Colors(A)<>Colors(C) And Colors(B)<>Colors(D):NewColors(N2) = Colors(B):EndIf
If Colors(B)=Colors(D) And Colors(B)<>Colors(A) And Colors(D)<>Colors(C):NewColors(N4) = Colors(D):EndIf
If Colors(D)=Colors(C) And Colors(D)<>Colors(B) And Colors(C)<>Colors(A):NewColors(N3) = Colors(C):EndIf
; optimized:
; If (A != D && C != B) {
; E0 = C == A ? C : P;
; E1 = A == B ? B : P;
; E2 = C == D ? C : P;
; E3 = D == B ? B : P;
; } Else {
; E0 = P;
; E1 = P;
; E2 = P;
; E3 = P;
If Colors(A)<>Colors(D) And Colors(C)<>Colors(B)
If Colors(C)=Colors(A):NewColors(N1)=Colors(C):Else: NewColors(N1)=Colors(P):EndIf
If Colors(A)=Colors(B):NewColors(N2)=Colors(B):Else: NewColors(N2)=Colors(P):EndIf
If Colors(C)=Colors(D):NewColors(N3)=Colors(C):Else: NewColors(N3)=Colors(P):EndIf
If Colors(D)=Colors(B):NewColors(N4)=Colors(B):Else: NewColors(N4)=Colors(P):EndIf
Else
NewColors(N1) = Colors(P):NewColors(N2) = Colors(P): NewColors(N3) = Colors(P):NewColors(N4)= Colors(P)
EndIf
Next
Next
img2=CreateImage(#PB_Any,ImageWidth(Img)*2,ImageHeight(Img)*2)
StartDrawing( ImageOutput(img2))
;Box(0,0,ImageWidth(Img)*2,ImageHeight(Img)*2,Colors(0,0))
For y = 2 To ImageHeight(img2) - 1
For x = 2 To ImageWidth(img2) - 1
Plot (x , y, NewColors(x,y))
Next
Next
StopDrawing()
GrabImage(img2,img3,2,2,ImageWidth(Img2)-3,ImageHeight(Img2)-3)
ProcedureReturn img3
EndProcedure
Eagle works as follows: for every in pixel we will generate 4 out pixels. First, set all 4 to the color of the in pixel we are currently scaling (as nearest-neighbor).
Next look at the three pixels above, to the left, and diagonally above left: if all three are the same color as each other, set the top left pixel of our output square to
that color in preference to the nearest-neighbor color. Work similarly for all four pixels, and then move to the next one.
first: |Then
. . . --\ CC |S T U --\ 1 2
. C . --/ CC |V C W --/ 3 4
. . . |X Y Z
| IF V==S==T => 1=S
| IF T==U==W => 2=U
| IF V==X==Y => 3=X
| IF W==Z==Y => 4=Z
PureBasic code
Code: Select all
Procedure Eagle(Img)
; 1=P; 2=P; 3=P; 4=P
; |S A U --\ 1 2
; |C P B --/ 3 4
; |R D Z
; | IF C==S==A => 1=S
; | IF A==U==B => 2=U
; | IF C==R==D => 3=R
; | IF B==Z==D => 4=Z
Dim Colors(ImageWidth(Img),ImageHeight(Img))
Dim NewColors(ImageWidth(Img)*2,ImageHeight(Img)*2)
StartDrawing( ImageOutput(Img))
For y = 0 To ImageHeight(Img)-1
For x = 0 To ImageWidth(Img) -1
Colors(x,y) = Point(x, y)
Next
Next
StopDrawing()
For y = 1 To ImageHeight(Img) - 1
For x = 1 To ImageWidth(Img) - 1
NewColors(N1) = Colors(P):NewColors(N2) = Colors(P): NewColors(N3) = Colors(P):NewColors(N4)= Colors(P)
If Colors(C)=Colors(S) And Colors(C)=Colors(A):NewColors(N1)=Colors(S):EndIf
If Colors(A)=Colors(U) And Colors(A)=Colors(B):NewColors(N2)=Colors(U):EndIf
If Colors(C)=Colors(R) And Colors(C)=Colors(D):NewColors(N3)=Colors(R):EndIf
If Colors(B)=Colors(Z) And Colors(B)=Colors(D):NewColors(N4)=Colors(Z):EndIf
Next
Next
img2=CreateImage(#PB_Any,ImageWidth(Img)*2,ImageHeight(Img)*2)
StartDrawing( ImageOutput(img2))
;Box(0,0,ImageWidth(Img)*2,ImageHeight(Img)*2,Colors(0,0))
For x = 2 To ImageWidth(img2) - 1
For y = 2 To ImageHeight(img2) - 1
Plot (x , y, NewColors(x,y))
Next
Next
StopDrawing()
GrabImage(img2,img3,2,2,ImageWidth(Img2)-3,ImageHeight(Img2)-3)
ProcedureReturn img3
EndProcedure
Before applying the algorithm
Original image 30х40 pixels
https://en.wikipedia.org/wiki/Pixel-art ... algorithms
Test code (zip file)
https://www.upload.ee/files/7972298/TestSprite.zip.html