Skia image not writing to a file at all.

387 views
Skip to first unread message

ar...@nextvr.com

unread,
Apr 3, 2017, 5:09:26 PM4/3/17
to skia-discuss

Hi, 


I am just trying to make a simple Skia program. A very simple program, but as I run this code, the output image file never writes anything. I am running this code on VS 2015 : Debug : x64 and included the skia.lib and OpenGL32.lib static libraries.

Can someone tell me why this simple example does not work?


cpp file
#include "skiaIncludes.h"
void draw(SkCanvas* canvas) {
SkPaint paint;
paint.setColor(SK_ColorWHITE);
canvas->drawPaint(paint);
}

int main ()
{
try {
FILE * pFile;
char buffer[100];

pFile = fopen("myfile.png", "wb");
                sk_sp<SkSurface> rasterSurface(
SkSurface::MakeRasterN32Premul(300, 300));
SkCanvas* rasterCanvas = rasterSurface->getCanvas();

//rasterCanvas->save();
rasterCanvas->translate(SkIntToScalar(128), SkIntToScalar(128));
rasterCanvas->rotate(SkIntToScalar(45));
SkRect rect = SkRect::MakeXYWH(-90.5f, -90.5f, 181.0f, 181.0f);
SkPaint paint;
paint.setColor(SK_ColorBLUE);
rasterCanvas->drawRect(rect, paint);
//rasterCanvas->restore();

                sk_sp<SkImage> img = rasterSurface->makeImageSnapshot();
sk_sp<SkData> png(img->encode(SkEncodedImageFormat::kPNG, 100));
rasterCanvas->drawImage(img, 0, 0);
png->MakeFromFILE(pFile);

                fclose(pFile);
}
catch (std::exception ex){
printf(ex.what());
}

return 0;
}


header file



#pragma once

#include "core/SkData.h"
#include "core/SkImage.h"
#include "core/SkStream.h"
#include "core/SkSurface.h"
#include "core/SkCanvas.h"
#include "core/SkGraphics.h"
#include "core/SkImageEncoder.h"
#include "gpu/gl/GrGLInterface.h"
#include "gpu/gl/GrGLExtensions.h"
#include <fstream>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <exception>
#include <iostream>


Mike Klein

unread,
Apr 3, 2017, 5:18:49 PM4/3/17
to skia-discuss
png->MakeFromFILE() calls a static method on SkData, MakeFromFILE(), which reads the file you pass and returns an sk_sp<SkData>.  In your case, it doesn't really do anything.

I think you want to use an SkFILEWStream, found in SkStreams.h.  Or just write the data in png yourself (using png->data() or png->bytes(), and png->size()).

NextVR, Inc. technology is protected by US Patents 8,451,320, 8,610,757, 9,204,127, 9,313,474, 9,538,160, 9,485,494 and 9,407,902 with additional patents pending. The information contained in this transmission contains privileged and confidential information. It is intended only for the use of the person(s) named above. If you are not the intended recipient, you are hereby notified that any review, dissemination, distribution or duplication of this communication is strictly prohibited. If you are not the intended recipient, please contact the sender by reply email and destroy all copies of the original message.

--
You received this message because you are subscribed to the Google Groups "skia-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to skia-discuss...@googlegroups.com.
To post to this group, send email to skia-d...@googlegroups.com.
Visit this group at https://groups.google.com/group/skia-discuss.
For more options, visit https://groups.google.com/d/optout.

Hal Canary

unread,
Apr 3, 2017, 5:18:59 PM4/3/17
to skia-discuss
SkData::MakeFromFILE() does not do what you think it does.  Try this:

    int main () {
        sk_sp<SkSurface> rasterSurface = 
            SkSurface::MakeRasterN32Premul(300, 300);
        SkCanvas* rasterCanvas = rasterSurface->getCanvas();

        rasterCanvas->translate(SkIntToScalar(128), SkIntToScalar(128));
        rasterCanvas->rotate(SkIntToScalar(45));
        SkRect rect = SkRect::MakeXYWH(-90.5f, -90.5f, 181.0f, 181.0f);
        SkPaint paint;
        paint.setColor(SK_ColorBLUE);
        rasterCanvas->drawRect(rect, paint);

        sk_sp<SkImage> img = rasterSurface->makeImageSnapshot();
        sk_sp<SkData> png(img->encode(SkEncodedImageFormat::kPNG, 100));

        FILE* pFile = fopen("myfile.png", "wb");
        assert(pFile);
        fwrite(png->data(), png->size(), 1, pFile);
        fclose(pFile);

        return 0;
    }


NextVR, Inc. technology is protected by US Patents 8,451,320, 8,610,757, 9,204,127, 9,313,474, 9,538,160, 9,485,494 and 9,407,902 with additional patents pending. The information contained in this transmission contains privileged and confidential information. It is intended only for the use of the person(s) named above. If you are not the intended recipient, you are hereby notified that any review, dissemination, distribution or duplication of this communication is strictly prohibited. If you are not the intended recipient, please contact the sender by reply email and destroy all copies of the original message.

--
You received this message because you are subscribed to the Google Groups "skia-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to skia-discuss+unsubscribe@googlegroups.com.

ar...@nextvr.com

unread,
Apr 3, 2017, 5:29:22 PM4/3/17
to skia-discuss
OOO MakrFromFILE which is to return data. Some example said that was the way to write to a file.....

Your example worked, thanks so much :)
To unsubscribe from this group and stop receiving emails from it, send an email to skia-discuss...@googlegroups.com.

Hal Canary

unread,
Apr 3, 2017, 6:50:58 PM4/3/17
to skia-discuss
On Mon, Apr 3, 2017 at 5:18 PM, 'Mike Klein' via skia-discuss <skia-d...@googlegroups.com> wrote:
I think you want to use an SkFILEWStream, found in SkStreams.h.  Or just write the data in png yourself (using png->data() or png->bytes(), and png->size()).

The following uses SkFILEWStream for maximum efficiency:

     bool write(SkImage* image, const char* path) {
        SkPixmap pixmap;
        std::vector<uint32_t> pixels;
        if (!image->peekPixels(&pixmap)) {
            SkImageInfo info = SkImageInfo::MakeN32Premul(image->dimensions());
            pixels.resize(info.width() * info.height());
            pixmap = SkPixmap(info, pixels.data(), info.width() * sizeof(uint32_t));
            if (!image->readPixels(&pixmap, 0, 0) {
                return false;
            }
        }
        SkFILEWStream wStream(path);
        return wStream.isValid() &&
               SkEncodeImage(&wStream, pixmap, SkEncodedImageFormat::kPNG, 100);
    }
    void draw(SkCanvas* canvas) {
        canvas->translate(128.0f, 128.0f);
        canvas->rotate(45.0f);
        SkPaint paint;
        paint.setColor(SK_ColorBLUE);
        canvas->drawRect({-90.5f, -90.5f, 181.0f, 181.0f}, paint);
    }
    int main () {
        auto rasterSurface = SkSurface::MakeRasterN32Premul(300, 300);
        draw(rasterSurface->getCanvas());
        sk_sp<SkImage> img = rasterSurface->makeImageSnapshot();
        return write(img.get(), "myfile.png") ? 0 : 1;
    }

Mike Klein

unread,
Apr 3, 2017, 9:35:24 PM4/3/17
to skia-discuss
For what it's worth, I'd suggest sticking with the simplest approach when writing an image to a .png file:

const char* path_to_file = ...;
sk_sp<SkData> png{image->encode()};
SkFILEWStream{path_to_file}.write(png->data(), png->size());

Encoding a .png is expensive enough that it makes tweaking the rest for efficiency pretty moot.

--
Reply all
Reply to author
Forward
0 new messages