JustPaste.it
import bpy
import gpu
import time
 
width = 32
height = 32
image_name = "buffer_img"
framebuffer = None
viewport_info = None
pixelBuffer = None
 
if not image_name in bpy.data.images:
    framebuffer_image = bpy.data.images.new(image_name , 32, 32, alpha=True )
else:
    framebuffer_image = bpy.data.images[image_name]
 
def draw():
    print("drawing")
    
    # get currently bound framebuffer
    framebuffer = gpu.state.active_framebuffer_get()
 
    # get information on current viewport 
    viewport_info = gpu.state.viewport_get()
    width = viewport_info[2]
    height = viewport_info[3]
 
    # Write copied data to image
    ######################################################
    # resize image obect to fit the current 3D View size
    framebuffer_image.scale(width, height)
    
    # obtain pixels from the framebuffer
    pixelBuffer = framebuffer.read_color(0, 0, width, height, 4, 0, 'FLOAT')
    
    # write all pixels into the blender image
    pixelBuffer.dimensions = width * height * 4
    framebuffer_image.pixels.foreach_set(pixelBuffer)
    framebuffer_image.filepath_raw = "/home/mm/Desktop/Additional/Temp/MyImage.png"
    framebuffer_image.save()
 
begin = time.time()
 
_handle_3d = bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'PRE_VIEW') # this draws the viewport objects alone (without grid)
 
for area in bpy.context.screen.areas:
    if area.type == 'VIEW_3D':
        area.tag_redraw()
 
bpy.types.SpaceView3D.draw_handler_remove(_handle_3d, 'WINDOW')
 
end = time.time()
print(f"Render took {end - begin} seconds")