У меня есть процедура Tcl, которая увеличивает изображение.
proc ShowWindow {wtitle zfactor imgdata} {
puts stdout "Now in the Tcl procedure ShowWindow!";
image create photo idata -data $imgdata; # create a photo image from the input data
image create photo the_window; # final window
the_window copy idata -zoom $zfactor $zfactor; # copy the original and magnify
wm title . $wtitle; # window title
wm resizable . false false; # no resizing in both x and y directions
catch {destroy .dwindow}; # since this procedure will be called multiple times
# we need to suppress the 'window name "dwindow" already exists in parent' message
label .dwindow -image the_window; # create a label to display the image
pack .dwindow; # display the image
}
Я хотел бы вызвать эту процедуру Tcl из C ++.
Я думаю, что «imgdata» является ByteArray. Это правильно?
Соответствующий фрагмент кода показан ниже:
// ...Tcl/Tk initialization omitted...
unsigned char *img; // PPM image data
int num_bytes; // PPM image file size
// ...routines to initialize img and num_bytes omitted...
Tcl_Obj *tcl_raw;
// transfer the PPM image data into Tcl_Obj
if (!(tcl_raw = Tcl_NewByteArrayObj(img, num_bytes))) {
cerr << "Tcl_NewByteArrayObj() failed!" << endl;
cerr << "Exiting..." << endl;
return 1;
} else {
cerr << "Tcl_NewByteArrayObj() succeeded!" << endl;
}
Tcl_IncrRefCount(tcl_raw); // is this really necessary?
// set the Tcl variable "imgdata" to the Tcl_Obj
if (Tcl_SetVar2Ex(tcl_interpreter, "imgdata", "", tcl_raw, TCL_LEAVE_ERR_MSG) == NULL) {
cerr << "Tcl_SetVar2Ex() failed!" << endl;
cerr << "Exiting..." << endl;
return 1;
} else {
cerr << "Tcl_SetVar2Ex() succeeded!" << endl;
}
// execute the Tcl procedure
if (Tcl_Eval(tcl_interpreter, "ShowWindow TheImage 8 $imgdata") != TCL_OK) {
cerr << "Tcl_Eval() failed!" << endl;
cerr << "Tcl_GetStringResult() = " << Tcl_GetStringResult(tcl_interpreter) << endl;
cerr << "Exiting..." << endl;
return 1;
} else {
cerr << "Tcl_Eval() succeeded!" << endl;
}
Сбой программы в Tcl_Eval (). Выход программы:
...
Tcl_NewByteArrayObj() succeeded!
Tcl_SetVar2Ex() succeeded!
Tcl_Eval() failed!
Tcl_GetStringResult() = can't read "imgdata": variable is array
Exiting...
Каков рекомендуемый способ сделать это?
Вы можете рассматривать тип Tcl ByteArrayObj как буфер, используя Tcl_ByteArraySetLength или Tcl_GetByteArrayFromObj, которые оба предоставляют вам доступ к части данных объекта Tcl.
Tcl_Obj *dataObj = Tcl_NewObj();
char *dataPtr = Tcl_SetByteArrayLength(dataObj, 1024);
Теперь вы можете использовать dataPtr для установки байтов в объекте. Функция Tcl_SetByteArrayLength сделает этот объект типом ByteArray.
Тем не менее, вы также можете посмотреть на imgscale который я использую для растяжения изображений Tk, и это использует различные режимы интерполяции, например:
image create photo thumbnail
::imgscale::bilinear $myphoto 64 64 thumbnail 1.0
чтобы уменьшить некоторые фотографии в миниатюру изображения.
Других решений пока нет …