From f6a2909ea328d6b55689cc1c95f59498a81b1864 Mon Sep 17 00:00:00 2001 From: Krzysztofz01 Date: Tue, 29 Aug 2023 10:55:14 +0200 Subject: [PATCH] ReadFrames updated to return RGBA image slice --- README.md | 9 +++------ video.go | 11 ++++++----- vidio_test.go | 5 +---- 3 files changed, 10 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index c4821ed..36a014d 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ go get github.com/AlexEidt/Vidio The `Video` struct stores data about a video file you give it. The code below shows an example of sequentially reading the frames of the given video. -Calling the `Read()` function will fill in the `Video` struct `framebuffer` with the next frame data as 8-bit RGBA data, stored in a flattened byte array in row-major order where each pixel is represented by four consecutive bytes representing the R, G, B and A components of that pixel. Note that the A (alpha) component will always be 255. When iteration over the entire video file is not required, we can lookup a specific frame by calling `ReadFrame(n int)`. By calling `ReadFrames(n ...int)`, we can immediately access multiple frames as `[][]byte` and skip the `framebuffer`. +Calling the `Read()` function will fill in the `Video` struct `framebuffer` with the next frame data as 8-bit RGBA data, stored in a flattened byte array in row-major order where each pixel is represented by four consecutive bytes representing the R, G, B and A components of that pixel. Note that the A (alpha) component will always be 255. When iteration over the entire video file is not required, we can lookup a specific frame by calling `ReadFrame(n int)`. By calling `ReadFrames(n ...int)`, we can immediately access multiple frames as a slice of RGBA images and skip the `framebuffer`. ```go vidio.NewVideo(filename string) (*vidio.Video, error) @@ -39,7 +39,7 @@ SetFrameBuffer(buffer []byte) error Read() bool ReadFrame(n int) error -ReadFrames(n ...int) ([][]byte, error) +ReadFrames(n ...int) ([]*image.RGBA, error) Close() ``` @@ -208,12 +208,9 @@ video, _ := vidio.NewVideo("video.mp4") frames, _ := video.ReadFrames(0, video.Frames() - 1) -img := image.NewRGBA(image.Rect(0, 0, video.Width(), video.Height())) for index, frame := range frames { - copy(img.Pix, frame) - f, _ := os.Create(fmt.Sprintf("%d.jpg", index)) - jpeg.Encode(f, img, nil) + jpeg.Encode(f, frame, nil) f.Close() } ``` diff --git a/video.go b/video.go index c377d7c..685cc26 100644 --- a/video.go +++ b/video.go @@ -2,6 +2,7 @@ package vidio import ( "fmt" + "image" "io" "os" "os/exec" @@ -305,9 +306,9 @@ func (video *Video) ReadFrame(n int) error { return nil } -// Read the N-amount of frames with the given indexes and return them as a slice of buffers. If one of +// Read the N-amount of frames with the given indexes and return them as a slice of RGBA image pointers. If one of // the indexes is out of range, the function will return an error. The frames are indexes from 0. -func (video *Video) ReadFrames(n ...int) ([][]byte, error) { +func (video *Video) ReadFrames(n ...int) ([]*image.RGBA, error) { if len(n) == 0 { return nil, fmt.Errorf("vidio: no frames indexes specified") } @@ -358,11 +359,11 @@ func (video *Video) ReadFrames(n ...int) ([][]byte, error) { os.Exit(1) }() - frames := make([][]byte, len(n)) + frames := make([]*image.RGBA, len(n)) for frameIndex := range frames { - frames[frameIndex] = make([]byte, video.width*video.height*video.depth) + frames[frameIndex] = image.NewRGBA(image.Rect(0, 0, video.width, video.height)) - if _, err := io.ReadFull(stdoutPipe, frames[frameIndex]); err != nil { + if _, err := io.ReadFull(stdoutPipe, frames[frameIndex].Pix); err != nil { return nil, fmt.Errorf("vidio: failed to read the ffmpeg cmd result to the image buffer: %w", err) } } diff --git a/vidio_test.go b/vidio_test.go index f0cb0cf..caf5567 100644 --- a/vidio_test.go +++ b/vidio_test.go @@ -410,11 +410,8 @@ func TestReadFramesShouldReturnCorrectFrames(t *testing.T) { t.Errorf("Failed to read frames: %s", err) } - for index, buffer := range frames { + for index, actualFrame := range frames { expectedFrame := expectedFrames[index] - actualFrame := image.NewRGBA(image.Rect(0, 0, 480, 270)) - copy(actualFrame.Pix, buffer) - for xIndex := 0; xIndex < expectedFrame.Bounds().Dx(); xIndex += 1 { for yIndex := 0; yIndex < expectedFrame.Bounds().Dy(); yIndex += 1 { eR, eG, eB, eA := expectedFrame.At(xIndex, yIndex).RGBA()