当前位置: 首页>>代码示例>>C++>>正文


C++ ImageBuf::reset方法代码示例

本文整理汇总了C++中ImageBuf::reset方法的典型用法代码示例。如果您正苦于以下问题:C++ ImageBuf::reset方法的具体用法?C++ ImageBuf::reset怎么用?C++ ImageBuf::reset使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在ImageBuf的用法示例。


在下文中一共展示了ImageBuf::reset方法的10个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。

示例1: main

int main (int argc, char *argv[])
{
    getargs (argc, argv);

    // Initialize
    imgA.reset (ImageSpec (xres, yres, channels, TypeDesc::FLOAT));
    imgB.reset (ImageSpec (xres, yres, channels, TypeDesc::FLOAT));
    imgR.reset (ImageSpec (xres, yres, channels, TypeDesc::FLOAT));
    float red[3]  = { 1, 0, 0 };
    float green[3] = { 0, 1, 0 };
    float blue[3]  = { 0, 0, 1 };
    float black[3] = { 0, 0, 0 };
    ImageBufAlgo::fill (imgA, red, green, red, green);
    ImageBufAlgo::fill (imgB, blue, blue, black, black);
    // imgA.write ("A.exr");
    // imgB.write ("B.exr");

    test_compute ();

    return unit_test_failures;
}
开发者ID:mor-vfx,项目名称:oiio,代码行数:21,代码来源:compute_test.cpp

示例2: spec

bool
ImageBufAlgo::make_kernel (ImageBuf &dst, string_view name,
                           float width, float height, float depth,
                           bool normalize)
{
    int w = std::max (1, (int)ceilf(width));
    int h = std::max (1, (int)ceilf(height));
    int d = std::max (1, (int)ceilf(depth));
    // Round up size to odd
    w |= 1;
    h |= 1;
    d |= 1;
    ImageSpec spec (w, h, 1 /*channels*/, TypeDesc::FLOAT);
    spec.depth = d;
    spec.x = -w/2;
    spec.y = -h/2;
    spec.z = -d/2;
    spec.full_x = spec.x;
    spec.full_y = spec.y;
    spec.full_z = spec.z;
    spec.full_width = spec.width;
    spec.full_height = spec.height;
    spec.full_depth = spec.depth;
    dst.reset (spec);

    if (Filter2D *filter = Filter2D::create (name, width, height)) {
        // Named continuous filter from filter.h
        for (ImageBuf::Iterator<float> p (dst);  ! p.done();  ++p)
            p[0] = (*filter)((float)p.x(), (float)p.y());
        delete filter;
    } else if (name == "binomial") {
        // Binomial filter
        float *wfilter = ALLOCA (float, width);
        for (int i = 0;  i < width;  ++i)
            wfilter[i] = binomial (width-1, i);
        float *hfilter = (height == width) ? wfilter : ALLOCA (float, height);
        if (height != width)
            for (int i = 0;  i < height;  ++i)
                hfilter[i] = binomial (height-1, i);
        float *dfilter = ALLOCA (float, depth);
        if (depth == 1)
            dfilter[0] = 1;
        else
            for (int i = 0;  i < depth;  ++i)
                dfilter[i] = binomial (depth-1, i);
        for (ImageBuf::Iterator<float> p (dst);  ! p.done();  ++p)
            p[0] = wfilter[p.x()-spec.x] * hfilter[p.y()-spec.y] * dfilter[p.z()-spec.z];
    } else {
开发者ID:jproccia,项目名称:oiio,代码行数:48,代码来源:imagebufalgo.cpp

示例3:

static bool
read_input (const std::string &filename, ImageBuf &img, 
            ImageCache *cache, int subimage=0, int miplevel=0)
{
    if (img.subimage() >= 0 && 
            img.subimage() == subimage && img.miplevel() == miplevel)
        return true;

    img.reset (filename, cache);
    if (img.read (subimage, miplevel, false, TypeDesc::TypeFloat))
        return true;

    std::cerr << "idiff ERROR: Could not read " << filename << ":\n\t"
              << img.geterror() << "\n";
    return false;
}
开发者ID:Zorroa,项目名称:oiio,代码行数:16,代码来源:idiff.cpp

示例4: ImageSpec

bool
ImageBufAlgo::histogram_draw (ImageBuf &R,
                              const std::vector<imagesize_t> &histogram)
{
    // Fail if there are no bins to draw.
    int bins = histogram.size();
    if (bins == 0) {
        R.error ("There are no bins to draw, the histogram is empty");
        return false;
    }

    // Check R and modify it if needed.
    int height = R.spec().height;
    if (R.spec().format != TypeDesc::TypeFloat || R.nchannels() != 1 ||
        R.spec().width != bins) {
        ImageSpec newspec = ImageSpec (bins, height, 1, TypeDesc::FLOAT);
        R.reset ("dummy", newspec);
    }

    // Fill output image R with white color.
    ImageBuf::Iterator<float, float> r (R);
    for ( ; ! r.done(); ++r)
        r[0] = 1;

    // Draw histogram left->right, bottom->up.
    imagesize_t max = *std::max_element (histogram.begin(), histogram.end());
    for (int b = 0; b < bins; b++) {
        int bin_height = (int) ((float)histogram[b]/(float)max*height + 0.5f);
        if (bin_height != 0) {
            // Draw one bin at column b.
            for (int j = 1; j <= bin_height; j++) {
                int row = height - j;
                r.pos (b, row);
                r[0] = 0;
            }
        }
    }
    return true;
}
开发者ID:JamieFinch,项目名称:oiio,代码行数:39,代码来源:imagebufalgo_compare.cpp

示例5: counts

bool
ImageBufAlgo::zover (ImageBuf &R, const ImageBuf &A, const ImageBuf &B,
                     bool z_zeroisinf, ROI roi, int nthreads)
{
    const ImageSpec &specR = R.spec();
    const ImageSpec &specA = A.spec();
    const ImageSpec &specB = B.spec();

    int nchannels_R, nchannels_A, nchannels_B;
    int alpha_R, alpha_A, alpha_B;
    int z_R, z_A, z_B;
    int colors_R, colors_A, colors_B;
    bool initialized_R = decode_over_channels (R, nchannels_R, alpha_R,
                                               z_R, colors_R);
    bool initialized_A = decode_over_channels (A, nchannels_A, alpha_A,
                                               z_A, colors_A);
    bool initialized_B = decode_over_channels (B, nchannels_B, alpha_B,
                                               z_B, colors_B);

    if (! initialized_A || ! initialized_B) {
        R.error ("Can't 'zover' uninitialized images");
        return false;
    }
    // Fail if the input images don't have a Z channel.
    if (z_A < 0 || z_B < 0 || (initialized_R && z_R < 0)) {
        R.error ("'zover' requires Z channels");
        return false;
    }
    // Fail if the input images don't have an alpha channel.
    if (alpha_A < 0 || alpha_B < 0 || (initialized_R && alpha_R < 0)) {
        R.error ("'zover' requires alpha channels");
        return false;
    }
    // Fail for mismatched channel counts
    if (colors_A != colors_B || colors_A < 1) {
        R.error ("Can't 'zover' images with mismatched color channel counts (%d vs %d)",
                 colors_A, colors_B);
        return false;
    }
    // Fail for unaligned alpha or z channels
    if (alpha_A != alpha_B || z_A != z_B ||
        (initialized_R && alpha_R != alpha_A) ||
        (initialized_R && z_R != z_A)) {
        R.error ("Can't 'zover' images with mismatched channel order",
                 colors_A, colors_B);
        return false;
    }
    
    // At present, this operation only supports ImageBuf's containing
    // float pixel data.
    if ((initialized_R && specR.format != TypeDesc::TypeFloat) ||
        specA.format != TypeDesc::TypeFloat ||
        specB.format != TypeDesc::TypeFloat) {
        R.error ("Unsupported pixel data format combination '%s = %s zover %s'",
                 specR.format, specA.format, specB.format);
        return false;
    }

    // Uninitialized R -> size it to the union of A and B.
    if (! initialized_R) {
        ImageSpec newspec = specA;
        set_roi (newspec, roi_union (get_roi(specA), get_roi(specB)));
        R.reset ("zover", newspec);
    }

    // Specified ROI -> use it. Unspecified ROI -> initialize from R.
    if (! roi.defined())
        roi = get_roi (R.spec());

    parallel_image (boost::bind (over_impl<float,float,float>, boost::ref(R),
                                 boost::cref(A), boost::cref(B), _1,
                                 true, z_zeroisinf),
                    roi, nthreads);
    return ! R.has_error();
}
开发者ID:jcrogel,项目名称:oiio,代码行数:75,代码来源:imagebufalgo_pixelmath.cpp

示例6: src


//.........这里部分代码省略.........
    Timer readtimer;
    if (! src.read (0, 0, read_local)) {
        std::cerr 
            << "maketx ERROR: Could not read \"" 
            << filenames[0] << "\" : " << src.geterror() << "\n";
        exit (EXIT_FAILURE);
    }
    stat_readtime += readtimer();
    
    // If requested - and we're a constant color - make a tiny texture instead
    std::vector<float> constantColor(src.nchannels());
    bool isConstantColor = ImageBufAlgo::isConstantColor (src, &constantColor[0]);
    
    if (isConstantColor && constant_color_detect) {
        int newwidth = std::max (1, std::min (src.spec().width, tile[0]));
        int newheight = std::max (1, std::min (src.spec().height, tile[1]));
        
        ImageSpec newspec = src.spec();
        newspec.x = 0;
        newspec.y = 0;
        newspec.z = 0;
        newspec.width = newwidth;
        newspec.height = newheight;
        newspec.depth = 1;
        newspec.full_x = 0;
        newspec.full_y = 0;
        newspec.full_z = 0;
        newspec.full_width = newspec.width;
        newspec.full_height = newspec.height;
        newspec.full_depth = newspec.depth;
        
        // Reset the image, to a new image, at the new size
        std::string name = src.name() + ".constant_color";
        src.reset(name, newspec);
        
        ImageBufAlgo::fill (src, &constantColor[0]);
        
        if (verbose) {
            std::cout << "  Constant color image detected. ";
            std::cout << "Creating " << newspec.width << "x" << newspec.height << " texture instead.\n";
        }
    }
    
    // If requested - and we're a monochrome image - drop the extra channels
    if (monochrome_detect && (src.nchannels() > 1) && ImageBufAlgo::isMonochrome(src)) {
        ImageBuf newsrc(src.name() + ".monochrome", src.spec());
        ImageBufAlgo::setNumChannels (newsrc, src, 1);
        src = newsrc;
        if (verbose) {
            std::cout << "  Monochrome image detected. Converting to single channel texture.\n";
        }
    }
    // Or, if we've otherwise explicitly requested to write out a
    // specific number of channels, do it.
    else if ((nchannels > 0) && (nchannels != src.nchannels())) {
        ImageBuf newsrc(src.name() + ".channels", src.spec());
        ImageBufAlgo::setNumChannels (newsrc, src, nchannels);
        src = newsrc;
        if (verbose) {
            std::cout << "  Overriding number of channels to " << nchannels << "\n";
        }
    }
    
    if (shadowmode) {
        // Some special checks for shadow maps
        if (src.spec().nchannels != 1) {
开发者ID:elrond79,项目名称:oiio,代码行数:67,代码来源:maketx.cpp

示例7: int

OIIO_NAMESPACE_BEGIN



bool
ImageBufAlgo::from_IplImage (ImageBuf &dst, const IplImage *ipl,
                             TypeDesc convert)
{
    if (! ipl) {
        DASSERT (0 && "ImageBufAlgo::fromIplImage called with NULL ipl");
        dst.error ("Passed NULL source IplImage");
        return false;
    }
#ifdef USE_OPENCV
    TypeDesc srcformat;
    switch (ipl->depth) {
    case int(IPL_DEPTH_8U) :
        srcformat = TypeDesc::UINT8;  break;
    case int(IPL_DEPTH_8S) :
        srcformat = TypeDesc::INT8;  break;
    case int(IPL_DEPTH_16U) :
        srcformat = TypeDesc::UINT16;  break;
    case int(IPL_DEPTH_16S) :
        srcformat = TypeDesc::INT16;  break;
    case int(IPL_DEPTH_32F) :
        srcformat = TypeDesc::FLOAT;  break;
    case int(IPL_DEPTH_64F) :
        srcformat = TypeDesc::DOUBLE;  break;
    default:
        DASSERT (0 && "unknown IplImage type");
        dst.error ("Unsupported IplImage depth %d", (int)ipl->depth);
        return false;
    }

    TypeDesc dstformat = (convert != TypeDesc::UNKNOWN) ? convert : srcformat;
    ImageSpec spec (ipl->width, ipl->height, ipl->nChannels, dstformat);
    // N.B. The OpenCV headers say that ipl->alphaChannel,
    // ipl->colorModel, and ipl->channelSeq are ignored by OpenCV.

    if (ipl->dataOrder != IPL_DATA_ORDER_PIXEL) {
        // We don't handle separate color channels, and OpenCV doesn't either
        dst.error ("Unsupported IplImage data order %d", (int)ipl->dataOrder);
        return false;
    }

    dst.reset (dst.name(), spec);
    size_t pixelsize = srcformat.size()*spec.nchannels;
    // Account for the origin in the line step size, to end up with the
    // standard OIIO origin-at-upper-left:
    size_t linestep = ipl->origin ? -ipl->widthStep : ipl->widthStep;
    // Block copy and convert
    convert_image (spec.nchannels, spec.width, spec.height, 1,
                   ipl->imageData, srcformat,
                   pixelsize, linestep, 0,
                   dst.pixeladdr(0,0), dstformat,
                   spec.pixel_bytes(), spec.scanline_bytes(), 0);
    // FIXME - honor dataOrder.  I'm not sure if it is ever used by
    // OpenCV.  Fix when it becomes a problem.

    // OpenCV uses BGR ordering
    // FIXME: what do they do with alpha?
    if (spec.nchannels >= 3) {
        float pixel[4];
        for (int y = 0;  y < spec.height;  ++y) {
            for (int x = 0;  x < spec.width;  ++x) {
                dst.getpixel (x, y, pixel, 4);
                float tmp = pixel[0];  pixel[0] = pixel[2]; pixel[2] = tmp;
                dst.setpixel (x, y, pixel, 4);
            }
        }
    }
    // FIXME -- the copy and channel swap should happen all as one loop,
    // probably templated by type.

    return true;
#else
    dst.error ("fromIplImage not supported -- no OpenCV support at compile time");
    return false;
#endif
}
开发者ID:AheadIO,项目名称:oiio,代码行数:80,代码来源:imagebufalgo_opencv.cpp

示例8: src


//.........这里部分代码省略.........
        outstream << "Reading file: " << filename << std::endl;
    Timer readtimer;
    if (! src.read (0, 0, read_local)) {
        outstream 
            << "maketx ERROR: Could not read \"" 
            << filename << "\" : " << src.geterror() << "\n";
        return false;
    }
    stat_readtime += readtimer();
    
    // If requested - and we're a constant color - make a tiny texture instead
    // Only safe if the full/display window is the same as the data window.
    // Also note that this could affect the appearance when using "black"
    // wrap mode at runtime.
    std::vector<float> constantColor(src.nchannels());
    bool isConstantColor = false;
    if (configspec.get_int_attribute("maketx:constant_color_detect") &&
        src.spec().x == 0 && src.spec().y == 0 && src.spec().z == 0 &&
        src.spec().full_x == 0 && src.spec().full_y == 0 &&
        src.spec().full_z == 0 && src.spec().full_width == src.spec().width &&
        src.spec().full_height == src.spec().height &&
        src.spec().full_depth == src.spec().depth) {
        isConstantColor = ImageBufAlgo::isConstantColor (src, &constantColor[0]);
        if (isConstantColor) {
            // Reset the image, to a new image, at the tile size
            ImageSpec newspec = src.spec();
            newspec.width  = std::min (configspec.tile_width, src.spec().width);
            newspec.height = std::min (configspec.tile_height, src.spec().height);
            newspec.depth  = std::min (configspec.tile_depth, src.spec().depth);
            newspec.full_width  = newspec.width;
            newspec.full_height = newspec.height;
            newspec.full_depth  = newspec.depth;
            std::string name = src.name() + ".constant_color";
            src.reset(name, newspec);
            ImageBufAlgo::fill (src, &constantColor[0]);
            if (verbose) {
                outstream << "  Constant color image detected. ";
                outstream << "Creating " << newspec.width << "x" << newspec.height << " texture instead.\n";
            }
        }
    }
    
    int nchannels = configspec.get_int_attribute ("maketx:nchannels", -1);

    // If requested -- and alpha is 1.0 everywhere -- drop it.
    if (configspec.get_int_attribute("maketx:opaque_detect") &&
          src.spec().alpha_channel == src.nchannels()-1 &&
          nchannels <= 0 &&
          ImageBufAlgo::isConstantChannel(src,src.spec().alpha_channel,1.0f)) {
        ImageBuf newsrc(src.name() + ".noalpha", src.spec());
        ImageBufAlgo::setNumChannels (newsrc, src, src.nchannels()-1);
        src.copy (newsrc);
        if (verbose) {
            outstream << "  Alpha==1 image detected. Dropping the alpha channel.\n";
        }
    }

    // If requested - and we're a monochrome image - drop the extra channels
    if (configspec.get_int_attribute("maketx:monochrome_detect") &&
          nchannels <= 0 &&
          src.nchannels() == 3 && src.spec().alpha_channel < 0 &&  // RGB only
          ImageBufAlgo::isMonochrome(src)) {
        ImageBuf newsrc(src.name() + ".monochrome", src.spec());
        ImageBufAlgo::setNumChannels (newsrc, src, 1);
        src.copy (newsrc);
        if (verbose) {
开发者ID:mmmovania,项目名称:PVR_Windows,代码行数:67,代码来源:maketexture.cpp

示例9: smf

bool
SMF::saveMinimap()
{
	if( verbose )cout << "INFO: saveMinimap\n";

	char filename[256];
	sprintf( filename, "%s.smf", outPrefix.c_str() );

	fstream smf(filename, ios::binary | ios::in | ios::out);
	smf.seekp(minimapPtr);

	unsigned char *pixels;
	if( is_smf(minimapFile) ) {
		// Copy from SMF
		pixels = new unsigned char[MINIMAP_SIZE];

		ifstream inFile(minimapFile.c_str(), ifstream::in);
		inFile.seekg(header.minimapPtr);
		inFile.read( (char *)pixels, MINIMAP_SIZE);
		inFile.close();

		smf.write( (char *)pixels, MINIMAP_SIZE);
		smf.close();
		delete [] pixels;
		return false;
	}

	//OpenImageIO
	ROI roi(	0, 1024,
				0, 1024,
				0, 1,
				0, 4);
	ImageSpec imageSpec( roi.xend, roi.yend, roi.chend, TypeDesc::UINT8 );
	

	// Load image file
	ImageBuf *imageBuf = new ImageBuf( minimapFile );
	imageBuf->read( 0, 0, false, TypeDesc::UINT8 );
//FIXME attempt to generate minimap from tile files.

	if( !imageBuf->initialized() ) {
		// Create from height
		imageBuf->reset( minimapFile );
		imageBuf->read( 0, 0, false, TypeDesc::UINT8 );
	}

	if( !imageBuf->initialized() ) {
		// Create blank
		imageBuf->reset( "minimap", imageSpec);
	}

	imageSpec = imageBuf->specmod();
	ImageBuf fixBuf;
	// Fix channels
	if( imageSpec.nchannels != roi.chend ) {
		int map[] = {2,1,0,3};
		float fill[] = {0,0,0,255};
		ImageBufAlgo::channels(fixBuf, *imageBuf, roi.chend, map, fill);
		imageBuf->copy(fixBuf);
		fixBuf.clear();
	}

	// Fix dimensions
	if( imageSpec.width != roi.xend || imageSpec.height != roi.yend ) {
		printf( "\tWARNING: %s is (%i,%i), wanted (%i, %i), Resampling.\n",
			minimapFile.c_str(), imageSpec.width, imageSpec.height, roi.xend, roi.yend );
		ImageBufAlgo::resample(fixBuf, *imageBuf, true, roi);
		imageBuf->copy(fixBuf);
		fixBuf.clear();
	}

	pixels = (unsigned char *)imageBuf->localpixels();

	// setup DXT1 Compression
	nvtt::InputOptions inputOptions;
	inputOptions.setTextureLayout( nvtt::TextureType_2D, 1024, 1024 );
	inputOptions.setMipmapData( pixels, 1024, 1024 );

	nvtt::CompressionOptions compressionOptions;
	compressionOptions.setFormat( nvtt::Format_DXT1 );
	if( slowcomp ) compressionOptions.setQuality( nvtt::Quality_Normal ); 
	else compressionOptions.setQuality( nvtt::Quality_Fastest ); 

	nvtt::OutputOptions outputOptions;
	outputOptions.setOutputHeader( false );

	NVTTOutputHandler *outputHandler = new NVTTOutputHandler(MINIMAP_SIZE + 1);
	outputOptions.setOutputHandler( outputHandler );

	nvtt::Compressor compressor;
	compressor.process( inputOptions, compressionOptions, outputOptions );

	// Write data to smf
	smf.write( outputHandler->buffer, MINIMAP_SIZE );
	delete outputHandler;

	smf.close();
	delete imageBuf;		
	return false;
}
开发者ID:pajohns,项目名称:MapConv,代码行数:100,代码来源:smf.cpp

示例10: roi

bool
SMF::saveHeight()
{
	if( verbose )cout << "INFO: saveHeight\n";
	// Dimensions of displacement map.
	ImageBuf *imageBuf = NULL;
	ROI roi(	0, width * 64 + 1,  // xbegin, xend
				0, length * 64 + 1, // ybegin, yend
				0, 1,               // zbegin, zend
				0, 1);              // chbegin, chend
	ImageSpec imageSpec( roi.xend, roi.yend, roi.chend, TypeDesc::UINT16 );

	if( is_smf(heightFile) ) {
		// Load from SMF
		SMF sourcesmf(heightFile);
		imageBuf = sourcesmf.getHeight();
	}
   	if( !imageBuf ) {
		// load image file
		imageBuf = new ImageBuf( heightFile );
		imageBuf->read( 0, 0, false, TypeDesc::UINT16 );
		if( !imageBuf->initialized() ) {
			delete imageBuf;
			imageBuf = NULL;
		}
	}
	if( !imageBuf ) {
		// Generate blank
		imageBuf = new ImageBuf( "height", imageSpec );
	}

	imageSpec = imageBuf->specmod();
	ImageBuf fixBuf;
	// Fix the number of channels
	if( imageSpec.nchannels != roi.chend ) {
		int map[] = {0};
		ImageBufAlgo::channels(fixBuf, *imageBuf, roi.chend, map);
		imageBuf->copy(fixBuf);
		fixBuf.clear();
	}

	// Fix the size
	if ( imageSpec.width != roi.xend || imageSpec.height != roi.yend ) {
		if( verbose )
			printf( "\tWARNING: %s is (%i,%i), wanted (%i, %i), Resampling.\n",
			heightFile.c_str(), imageSpec.width, imageSpec.height, roi.xend, roi.yend );
		ImageBufAlgo::resample(fixBuf, *imageBuf, true, roi);
		imageBuf->copy(fixBuf);
		fixBuf.clear();
	}

	// Invert height
	if ( invert ) {
		ImageSpec fixSpec(roi.xend, roi.yend, roi.chend, TypeDesc::UINT16);
		fixBuf.reset( "fixBuf",  fixSpec );
		const float fill[] = {65535};
		ImageBufAlgo::fill(fixBuf, fill);
		ImageBufAlgo::sub(*imageBuf, fixBuf, *imageBuf);
		fixBuf.clear();
	}

	// FIXME filter to remove stepping artifacts from 8bit images,
//	if ( lowpass ) {
//	}
	
	unsigned short *pixels = (unsigned short *)imageBuf->localpixels();

	// write height data to smf.
	char filename[256];
	sprintf( filename, "%s.smf", outPrefix.c_str() );

	fstream smf(filename, ios::binary | ios::in| ios::out);
	smf.seekp(heightPtr);

	smf.write( (char *)pixels, imageBuf->spec().image_bytes() );
	smf.close();
	delete imageBuf;
	if( is_smf( heightFile ) ) delete [] pixels;

	return false;
}
开发者ID:pajohns,项目名称:MapConv,代码行数:81,代码来源:smf.cpp


注:本文中的ImageBuf::reset方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。