potrace_bitmap_t *bitmapFromImage(const QImage &image,
                                  int threshold)
{
  // De momento no implementamos que la imagen no tenga alpha channel
//  Q_ASSERT(image.hasAlphaChannel());

  potrace_bitmap_t *bitmap = bm_new(image.width(), image.height());
  int pi = 0;
  for(int i = 0; i < image.byteCount(); i += 4)
  {
    int x = pi % image.width();
    int y = pi / image.width();
    int p;
    if(image.hasAlphaChannel())
    {
      p = (image.bits()[i+3] > threshold)? 1 : 0;
    }
    else
    {
      p = (image.bits()[i] > threshold)? 0 : 1;
    }
    BM_PUT(bitmap, x, y, p);

    ++pi;
  }

  return bitmap;
}
int main() {
    int x, y, i;
    potrace_bitmap_t *bm;
    potrace_param_t *param;
    potrace_path_t *p;
    potrace_state_t *st;
    int n, *tag;
    potrace_dpoint_t(*c)[3];

    /* create a bitmap */
    bm = bm_new(WIDTH, HEIGHT);
    if (!bm) {
        fprintf(stderr, "Error allocating bitmap: %s\n", strerror(errno));
        return 1;
    }

    /* fill the bitmap with some pattern */
    for (y = 0; y < HEIGHT; y++) {
        for (x = 0; x < WIDTH; x++) {
            BM_PUT(bm, x, y, ((x * x + y * y * y) % 10000 < 5000) ? 1 : 0);
        }
    }

    /* set tracing parameters, starting from defaults */
    param = potrace_param_default();
    if (!param) {
        fprintf(stderr, "Error allocating parameters: %s\n", strerror(errno));
        return 1;
    }
    param->turdsize = 0;

    /* trace the bitmap */
    st = potrace_trace(param, bm);
    if (!st || st->status != POTRACE_STATUS_OK) {
        fprintf(stderr, "Error tracing bitmap: %s\n", strerror(errno));
        return 1;
    }
    bm_free(bm);

    /* output vector data, e.g. as a rudimentary EPS file */
    printf("%%!PS-Adobe-3.0 EPSF-3.0\n");
    printf("%%%%BoundingBox: 0 0 %d %d\n", WIDTH, HEIGHT);
    printf("gsave\n");

    /* draw each curve */
    p = st->plist;
    while (p != NULL) {
        n = p->curve.n;
        tag = p->curve.tag;
        c = p->curve.c;
        printf("%f %f moveto\n", c[n - 1][2].x, c[n - 1][2].y);
        for (i = 0; i < n; i++) {
            switch (tag[i]) {
            case POTRACE_CORNER:
                printf("%f %f lineto\n", c[i][1].x, c[i][1].y);
                printf("%f %f lineto\n", c[i][2].x, c[i][2].y);
                break;
            case POTRACE_CURVETO:
                printf("%f %f %f %f %f %f curveto\n", c[i][0].x, c[i][0].y, c[i][1].x, c[i][1].y,
                       c[i][2].x, c[i][2].y);
                break;
            }
        }
        /* at the end of a group of a positive path and its negative
           children, fill. */
        if (p->next == NULL || p->next->sign == '+') {
            printf("0 setgray fill\n");
        }
        p = p->next;
    }
    printf("grestore\n");
    printf("%%EOF\n");

    potrace_state_free(st);
    potrace_param_free(param);

    return 0;
}
Example #3
0
JNIEXPORT jobject JNICALL Java_com_jiangpeng_android_antrace_Utils_traceImage(JNIEnv* env, jobject thiz, jobject bitmap)
{
	AndroidBitmapInfo info;
	int ret = 0;
	void* src_pixels = 0;

	if ((ret = AndroidBitmap_getInfo(env, bitmap, &info)) < 0) {
		return NULL;
	}

	if (info.format != ANDROID_BITMAP_FORMAT_RGBA_8888) {
		return NULL;
	}
	if ((ret = AndroidBitmap_lockPixels(env, bitmap, &src_pixels)) < 0) {
		return NULL;
	}

	potrace_param_t* param_t = potrace_param_default();
    param_t->turdsize = 15;
    param_t->opttolerance = 0.8;
	potrace_bitmap_t* bmp_t = bm_new(info.width, info.height);
	//memcpy(bmp_t->map, src_pixels, bmp_t->dy * bmp_t->h * BM_WORDSIZE);

	const int kShiftBits = 20;
	const int32_t kRedRatio = static_cast<int32_t>((1 << kShiftBits) * 0.21f);
	const int32_t kGreenRatio = static_cast<int32_t>((1 << kShiftBits) * 0.71f);
	const int32_t kBlueRatio = static_cast<int32_t>((1 << kShiftBits) * 0.07f);
	for (uint32_t scan_line = 0; scan_line < info.height; scan_line++) {
	    pixel32_t* src = reinterpret_cast<pixel32_t*>(src_pixels);
	    pixel32_t* src_line_end = src + info.width;
	    int x = 0;
	    while (src < src_line_end) {
	    	int32_t src_red = src->rgba8[0];
	    	int32_t src_green = src->rgba8[1];
	    	int32_t src_blue = src->rgba8[2];
	    	int32_t src_alpha = src->rgba8[3];

	    	int32_t dst_color = (kRedRatio * src_red + kGreenRatio * src_green +
	    			kBlueRatio * src_blue) >> kShiftBits;
	    	if (dst_color > 128) {
    	      BM_PUT(bmp_t, x, info.height - 1 - scan_line, 1);
	    	}
	    	else
	    	{
    	      BM_PUT(bmp_t, x, info.height - 1 - scan_line, 0);
	    	}
	    	src++;
	    	++x;
	    }
	    src_pixels = reinterpret_cast<char*>(src_pixels) + info.stride;
	}
	if(s_state != NULL)
	{
		potrace_state_free(s_state);
		s_state = NULL;
	}
	s_state = potrace_trace(param_t, bmp_t);
	potrace_param_free(param_t);
	bm_free(bmp_t);

	AndroidBitmap_unlockPixels(env, bitmap);

    if (!s_state || s_state->status != POTRACE_STATUS_OK) {
    	return NULL;
    }

    potrace_path_t* start = s_state->plist;
    jobject prev = 0;
    jclass cls = env->FindClass("com/jiangpeng/android/antrace/Objects/path");
    jobject retPath = 0;
    for(potrace_path_t* n = start; n != 0; n = n->next)
    {
    	jobject path = createPath(env, n);
    	if(retPath == 0)
    	{
    		retPath = path;
    	}
    	if(prev != 0)
    	{
    		jfieldID fid = env->GetFieldID(cls, "next", "Lcom/jiangpeng/android/antrace/Objects/path;");
    		env->SetObjectField(prev, fid, path);
    		env->DeleteLocalRef(prev);
    	}
    	prev = path;
    }
    env->DeleteLocalRef(cls);
	return retPath;
}