Page 1 of 1

Scale2x algorithm that depixelizes and upscales low-resoluti

Posted: Thu Feb 01, 2018 11:42 am
by kvitaliy
EPX/Scale2×

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
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
Scale2x algorithm that depixelizes and upscales low-resolution 8-bit “pixel art”

Image

Before applying the algorithm

Image


Original image 30х40 pixels

Image

https://en.wikipedia.org/wiki/Pixel-art ... algorithms


Test code (zip file)
https://www.upload.ee/files/7972298/TestSprite.zip.html

Re: Scale2x algorithm that depixelizes and upscales low-reso

Posted: Thu Feb 01, 2018 3:43 pm
by J. Baker
Thanks for sharing the code but I prefer the pixels. ;)

Re: Scale2x algorithm that depixelizes and upscales low-reso

Posted: Thu Feb 01, 2018 4:01 pm
by kvitaliy
J. Baker wrote: but I prefer the pixels. ;)
Ок! Many men, many minds. Tastes differ :D

Re: Scale2x algorithm that depixelizes and upscales low-reso

Posted: Thu Feb 01, 2018 4:19 pm
by wilbert
Nice work :)

Looking at the Wikipedia page you mentioned, I was surprised by the quality of the hqnx family and the xBR family.

Re: Scale2x algorithm that depixelizes and upscales low-reso

Posted: Fri Feb 02, 2018 10:04 am
by walbus
Very nice

Re: Scale2x algorithm that depixelizes and upscales low-reso

Posted: Fri Feb 02, 2018 11:51 am
by acreis
Great! Thanks for sharing!

Re: Scale2x algorithm that depixelizes and upscales low-reso

Posted: Tue Feb 06, 2018 10:28 am
by Kwai chang caine
Thanks for sharing 8)

Re: Scale2x algorithm that depixelizes and upscales low-reso

Posted: Tue Feb 06, 2018 3:05 pm
by davido
Excellent! Thank you for sharing.

Re: Scale2x algorithm that depixelizes and upscales low-reso

Posted: Tue Feb 06, 2018 10:39 pm
by Fred
Interesting upscale algo

Re: Scale2x algorithm that depixelizes and upscales low-reso

Posted: Sat Feb 10, 2018 3:54 pm
by walbus
A little Hint
The procedure above is not runnable

Re: Scale2x algorithm that depixelizes and upscales low-reso

Posted: Sun Feb 11, 2018 6:20 am
by kvitaliy
walbus wrote:A little Hint
The procedure above is not runnable
For work it is necessary to take MACRO from the very first code

Re: Scale2x algorithm that depixelizes and upscales low-reso

Posted: Sun Feb 11, 2018 9:58 am
by wilbert
If performance is important, you probably could optimize things by not using Point and Plot.

Re: Scale2x algorithm that depixelizes and upscales low-reso

Posted: Sun Feb 11, 2018 12:16 pm
by kvitaliy
wilbert wrote:If performance is important, you probably could optimize things by not using Point and Plot.
I think that it is possible to optimize. But for me the principle of such work, rather than practical application, was more important.
If someone will bring this code to perfection, then I will be very happy!

Re: Scale2x algorithm that depixelizes and upscales low-reso

Posted: Sun Feb 11, 2018 12:24 pm
by walbus
I meant that it is helpful if the posted codes are directly executable.

For the low resolutions on which it is based, doubling with point and plot should always be fast enough.